0

我喜欢使用 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的非迭代解决方案,只迭代并做count ++会更好吗?

4

3 回答 3

7

FluentIterable.from(foo).filter(predicate).isEmpty()不会进行任何迭代。

但是,如果您需要大小,那么您真的想使用FluentIterable.from(foo).filter(predicate).size(),它不会存储元素,而只会计算与谓词匹配的元素。

于 2012-09-29T02:51:28.040 回答
1

路易斯的回答是正确的。由于您碰巧正在使用 a Collection,因此也可以使用Collections2.filter

Collection<Foo> filteredFoos = Collections2.filter(foos, fooPredicate);
if (filteredFoos.isEmpty()) {
    ...
}

从文档中:

unfiltered返回满足谓词的元素。返回的集合是unfiltered; 一个变化会影响另一个。

于 2012-09-29T02:57:24.853 回答
1

没有迭代就无法获得过滤的大小,Iterable因为您不知道哪些元素将匹配。为什么不直接使用Iterables.size?如果没有元素与您的谓词匹配,isEmpty则无论如何都必须遍历整个集合。

于 2012-09-29T14:06:25.837 回答