java-8 过滤列表而不创建新列表
Posted
技术标签:
【中文标题】java-8 过滤列表而不创建新列表【英文标题】:java-8 filter a list without creating a new list 【发布时间】: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));
(另外,我更喜欢不涉及使用第三方库或框架的解决方案)
【问题讨论】:
不错的变量名。 :P 查看github.com/wapatesh/fig,很多情况下你可能需要它 【参考方案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) 操作并且使用 removeIf
的 default 实现的任何列表仍然适用在Collection
接口中定义的...
无需道歉。不要删除评论。在处理默认方法时问自己这样一个问题很有用,它可能会消除未来读者的疑虑。我自己必须检查文档(和代码)以确保 ArrayList 覆盖了该方法。
@Marco13 我同意 JB Nizet 的观点;这是一个有用的讨论。还可能值得注意的是,使用Iterator
并一次删除一个匹配元素的传统方法可能具有 O(n^2) 性能,至少对于ArrayList
。以上是关于java-8 过滤列表而不创建新列表的主要内容,如果未能解决你的问题,请参考以下文章