我想根据谓词筛选java.util.Collection。


当前回答

“最好”这个要求太宽泛了。它是“最短的”吗?“最快”?“可读”? 过滤器的地方或到另一个集合?

最简单(但不是最易读)的方法是迭代它,并使用Iterator.remove()方法:

Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
  Foo foo = it.next();
  if( !condition(foo) ) it.remove();
}

现在,为了使其更具可读性,可以将其包装到实用程序方法中。然后发明一个IPredicate接口,创建该接口的匿名实现,并执行如下操作:

CollectionUtils.filterInPlace(col,
  new IPredicate<Foo>(){
    public boolean keepIt(Foo foo) {
      return foo.isBar();
    }
  });

where filterInPlace()迭代集合并调用Predicate.keepIt()来了解实例是否保留在集合中。

我真的没有看到为这项任务引入第三方库的正当理由。

其他回答

您确定要筛选Collection本身,而不是迭代器吗?

看到org.apache.commons.collections.iterators.FilterIterator

或者使用apache commons的第四版org.apache.commons.collections4.iterators.FilterIterator

这一点,再加上缺少真正的闭包,是我对Java最大的不满。 老实说,上面提到的大多数方法都很容易阅读,而且真的很有效;然而,在学习了。net、Erlang等之后……在语言级别集成的列表理解使一切变得更加清晰。如果没有在语言级别上的添加,Java就不能像这个领域的许多其他语言一样干净。

如果性能非常重要,那么可以使用谷歌集合(或者编写自己的简单谓词实用程序)。Lambdaj语法对某些人来说可读性更好,但效率不高。

然后有一个我写的库。我将忽略任何关于其效率的问题(是的,它很糟糕)......是的,我知道它清楚地基于反射,不,我实际上没有使用它,但它确实工作:

LinkedList<Person> list = ......
LinkedList<Person> filtered = 
           Query.from(list).where(Condition.ensure("age", Op.GTE, 21));

OR

LinkedList<Person> list = ....
LinkedList<Person> filtered = Query.from(list).where("x => x.age >= 21");

“最好”这个要求太宽泛了。它是“最短的”吗?“最快”?“可读”? 过滤器的地方或到另一个集合?

最简单(但不是最易读)的方法是迭代它,并使用Iterator.remove()方法:

Iterator<Foo> it = col.iterator();
while( it.hasNext() ) {
  Foo foo = it.next();
  if( !condition(foo) ) it.remove();
}

现在,为了使其更具可读性,可以将其包装到实用程序方法中。然后发明一个IPredicate接口,创建该接口的匿名实现,并执行如下操作:

CollectionUtils.filterInPlace(col,
  new IPredicate<Foo>(){
    public boolean keepIt(Foo foo) {
      return foo.isBar();
    }
  });

where filterInPlace()迭代集合并调用Predicate.keepIt()来了解实例是否保留在集合中。

我真的没有看到为这项任务引入第三方库的正当理由。

使用来自Apache Commons的CollectionUtils.filter(Collection,Predicate)。

我的回答建立在Kevin Wong的基础上,这里是一个使用spring中的CollectionUtils和Java 8 lambda表达式的一行程序。

CollectionUtils.filter(list, p -> ((Person) p).getAge() > 16);

这是我见过的最简洁易读的方法(不使用基于方面的库)。

Spring CollectionUtils可从Spring版本4.0.2获得。请记住,您需要JDK 1.8和语言级别8+。