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


当前回答

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

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

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

其他回答

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".

等待Java 8:

List<Person> olderThan30 = 
  //Create a Stream from the personList
  personList.stream().
  //filter the element to select only those with age >= 30
  filter(p -> p.age >= 30).
  //put those filtered elements into a new List.
  collect(Collectors.toList());

让我们看看如何使用Eclipse Collections筛选内置JDK List和MutableList。

List<Integer> jdkList = Arrays.asList(1, 2, 3, 4, 5);
MutableList<Integer> ecList = Lists.mutable.with(1, 2, 3, 4, 5);

如果希望过滤小于3的数字,则会得到以下输出。

List<Integer> selected = Lists.mutable.with(1, 2);
List<Integer> rejected = Lists.mutable.with(3, 4, 5);

下面介绍如何使用Java 8 lambda作为Predicate进行筛选。

Assert.assertEquals(selected, Iterate.select(jdkList, each -> each < 3));
Assert.assertEquals(rejected, Iterate.reject(jdkList, each -> each < 3));

Assert.assertEquals(selected, ecList.select(each -> each < 3));
Assert.assertEquals(rejected, ecList.reject(each -> each < 3));

下面介绍如何使用匿名内部类作为Predicate进行筛选。

Predicate<Integer> lessThan3 = new Predicate<Integer>()
{
    public boolean accept(Integer each)
    {
        return each < 3;
    }
};

Assert.assertEquals(selected, Iterate.select(jdkList, lessThan3));
Assert.assertEquals(selected, ecList.select(lessThan3));

下面是一些使用Predicates工厂过滤JDK列表和Eclipse Collections mutabllists的替代方案。

Assert.assertEquals(selected, Iterate.select(jdkList, Predicates.lessThan(3)));
Assert.assertEquals(selected, ecList.select(Predicates.lessThan(3)));

下面是一个不为谓词分配对象的版本,而是使用Predicates2工厂,并使用selectWith方法接受Predicate2。

Assert.assertEquals(
    selected, ecList.selectWith(Predicates2.<Integer>lessThan(), 3));

有时你想过滤一个消极的条件。在Eclipse Collections中有一个特殊的方法叫做reject。

Assert.assertEquals(rejected, Iterate.reject(jdkList, lessThan3));
Assert.assertEquals(rejected, ecList.reject(lessThan3));

方法分区将返回两个集合,包含Predicate选择和拒绝的元素。

PartitionIterable<Integer> jdkPartitioned = Iterate.partition(jdkList, lessThan3);
Assert.assertEquals(selected, jdkPartitioned.getSelected());
Assert.assertEquals(rejected, jdkPartitioned.getRejected());

PartitionList<Integer> ecPartitioned = gscList.partition(lessThan3);
Assert.assertEquals(selected, ecPartitioned.getSelected());
Assert.assertEquals(rejected, ecPartitioned.getRejected());

注意:我是Eclipse Collections的提交者。

在Java 8中,您可以直接使用此过滤器方法,然后执行此操作。

 List<String> lines = Arrays.asList("java", "pramod", "example");

 List<String> result = lines.stream()              
         .filter(line -> !"pramod".equals(line))     
         .collect(Collectors.toList());              

 result.forEach(System.out::println); 

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