Guava:为什么没有Lists.filter()函数?

2022-08-31 11:52:08

有没有理由

Lists.transform()

但没有

Lists.filter()

?

如何正确筛选列表?我可以使用

new ArrayList(Collection2.filter())

当然,但是如果我理解正确,这种方式并不能保证我的排序保持不变。


答案 1

它没有实现,因为它会暴露大量危险的慢速方法,例如返回的List视图上的#get(index)(邀请性能错误)。ListIterator的实现起来也很痛苦(尽管我几年前提交了一个补丁来涵盖这一点)。

由于索引方法在筛选的列表视图中效率不高,因此最好只使用没有索引的已筛选迭代。


答案 2

您可以使用 ,这肯定会保持排序。Iterables.filter

请注意,通过构建新列表,您将复制元素(当然只是引用) - 因此它不会是原始列表的实时视图。创建视图将非常棘手 - 请考虑以下情况:

Predicate<StringBuilder> predicate = 
    /* predicate returning whether the builder is empty */
List<StringBuilder> builders = Lists.newArrayList();
List<StringBuilder> view = Lists.filter(builders, predicate);

for (int i = 0; i < 10000; i++) {
    builders.add(new StringBuilder());
}
builders.get(8000).append("bar");

StringBuilder firstNonEmpty = view.get(0);

这必须循环访问整个原始列表,将筛选器应用于所有内容。我想它可能要求谓词匹配在视图的生命周期内没有变化,但这并不完全令人满意。

(这只是猜测,请注意。也许番石榴维护者之一会加入真正的原因:)