我想根据谓词筛选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()来了解实例是否保留在集合中。

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

其他回答

我写了一个扩展的Iterable类,它支持在不复制集合内容的情况下应用函数式算法。

用法:

List<Integer> myList = new ArrayList<Integer>(){ 1, 2, 3, 4, 5 }

Iterable<Integer> filtered = Iterable.wrap(myList).select(new Predicate1<Integer>()
{
    public Boolean call(Integer n) throws FunctionalException
    {
        return n % 2 == 0;
    }
})

for( int n : filtered )
{
    System.out.println(n);
}

上面的代码将实际执行

for( int n : myList )
{
    if( n % 2 == 0 ) 
    {
        System.out.println(n);
    }
}

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

使用java 8,特别是lambda表达式,你可以像下面的例子那样简单:

myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())

其中,对于myProducts集合中的每个产品,如果prodc .price>10,则将该产品添加到新的过滤列表中。

一些简单明了的Java代码怎么样

 List<Customer> list ...;
 List<Customer> newList = new ArrayList<>();
 for (Customer c : list){
    if (c.getName().equals("dd")) newList.add(c);
 }

简单、易读、简单(在Android上也适用!) 但如果你使用的是Java 8,你可以用一句简单的话来实现:

List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());

注意,toList()是静态导入的

JFilter http://code.google.com/p/jfilter/最适合您的需求。

JFilter是一个简单、高性能的开源库,用于查询Java bean集合。

关键特性

Support of collection (java.util.Collection, java.util.Map and Array) properties. Support of collection inside collection of any depth. Support of inner queries. Support of parameterized queries. Can filter 1 million records in few 100 ms. Filter ( query) is given in simple json format, it is like Mangodb queries. Following are some examples. { "id":{"$le":"10"} where object id property is less than equals to 10. { "id": {"$in":["0", "100"]}} where object id property is 0 or 100. {"lineItems":{"lineAmount":"1"}} where lineItems collection property of parameterized type has lineAmount equals to 1. { "$and":[{"id": "0"}, {"billingAddress":{"city":"DEL"}}]} where id property is 0 and billingAddress.city property is DEL. {"lineItems":{"taxes":{ "key":{"code":"GST"}, "value":{"$gt": "1.01"}}}} where lineItems collection property of parameterized type which has taxes map type property of parameteriszed type has code equals to GST value greater than 1.01. {'$or':[{'code':'10'},{'skus': {'$and':[{'price':{'$in':['20', '40']}}, {'code':'RedApple'}]}}]} Select all products where product code is 10 or sku price in 20 and 40 and sku code is "RedApple".