我喜欢使用Guava的Iterables过滤器。但是一个常见的代码片段如下:
List foo = Lists.newArrayList(Iterables.filter(someCollection, somePredicate));
if (foo.isEmpty) {
// do empty
} else {
int count = foo.size(); // do non-empty
}
这很浪费,因为我真的不需要构建“foo”列表,我只需要知道它是否为空,并获得元素数量的计数。
我想知道最佳做法:
1)如何测试isEmpty()
而不浪费时间将列表构建到内存中
2)有没有办法在不迭代所有条目的情况下获得大小?
3)如果#2没有非迭代解决方案,那么迭代并计算++会更好吗?
答案 0 :(得分:7)
FluentIterable.from(foo).filter(predicate).isEmpty()
不会进行任何迭代。
但是如果你需要这个大小,那么你真的想要使用FluentIterable.from(foo).filter(predicate).size()
,它不会存储元素,而只会计算与谓词匹配的元素。
答案 1 :(得分:1)
路易斯的回答是正确的。由于您恰好使用Collection
,因此也可以使用Collections2.filter
:
Collection<Foo> filteredFoos = Collections2.filter(foos, fooPredicate);
if (filteredFoos.isEmpty()) {
...
}
来自文档:
返回满足谓词的
unfiltered
元素。该 返回的集合是unfiltered
的实时视图;变为一 影响对方。
答案 2 :(得分:1)
由于您不知道哪些元素会匹配,因此无法在不进行迭代的情况下获得已过滤的Iterable
的大小。为什么不使用Iterables.size
?如果没有元素与您的谓词匹配,isEmpty
无论如何都必须遍历整个集合。