【问题标题】:java-8 filter a list without creating a new listjava-8 过滤列表而不创建新列表
【发布时间】:2015-10-23 23:22:35
【问题描述】:

我正在寻找在 Java-8 中过滤列表的最简洁方法,使用简单的 lambda Predicate无需创建新列表

这个解决方案尤其不适合,因为toList() 返回一个新的List

List<Person> beerDrinkers = persons.stream()
    .filter(p -> p.getAge() > 16)
    .collect(Collectors.toList());

请注意,以下解决方案也不起作用,因为列表应该是其原始值的clear()ed(但显然,如果您在过滤之前将其清除,则没有什么可过滤的了。 ..):

persons.stream()
    .filter(p -> p.getAge() > 16)
    .forEach((p) -> persons.add(p));

(另外,我更喜欢不涉及使用第三方库或框架的解决方案)

【问题讨论】:

标签: java list lambda java-8


【解决方案1】:
beerDrinkers.removeIf(p -> p.getAge() <= 16);

【讨论】:

  • 附注:这可能有一个二次渐近的运行时间(取决于列表的类型),而过滤和收集总是 O(n)
  • @Marco13 它不会与 ArrayList 或 LinkedList 一起使用,但它们是迄今为止最常用的列表。您是否考虑过具体的 List 实现?
  • @JBNizet 抱歉,我认为 ArrayList 的 O(n²),因为 ArrayList 上 remove(E) 的 O(n),但实际上,有一个专门的实现对于ArrayList 中的removeIf,它使用BitSet 首先找出要删除的元素,然后在一次运行中压缩ArrayList 的元素。现在我考虑删除上面的评论(和这条评论),尽管对于 remove(E) 是 O(n) 操作并且使用 removeIfdefault 实现的任何列表仍然适用在Collection 接口中定义的...
  • 无需道歉。不要删除评论。在处理默认方法时问自己这样一个问题很有用,它可能会消除未来读者的疑虑。我自己必须检查文档(和代码)以确保 ArrayList 覆盖了该方法。
  • @Marco13 我同意 JB Nizet 的观点;这是一个有用的讨论。还可能值得注意的是,使用Iterator 并一次删除一个匹配元素的传统方法可能具有 O(n^2) 性能,至少对于ArrayList
猜你喜欢
  • 2017-06-21
  • 2015-07-12
  • 1970-01-01
  • 2021-12-20
  • 2021-07-01
  • 1970-01-01
  • 2018-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多