What is the best way to filter a Java Collection?

后端 未结 27 3334
故里飘歌
故里飘歌 2020-11-21 06:55

I want to filter a java.util.Collection based on a predicate.

27条回答
  •  野性不改
    2020-11-21 07:43

    Let’s look at how to filter a built-in JDK List and a MutableList using Eclipse Collections.

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

    If you wanted to filter the numbers less than 3, you would expect the following outputs.

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

    Here’s how you can filter using a Java 8 lambda as the 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));
    

    Here’s how you can filter using an anonymous inner class as the Predicate.

    Predicate lessThan3 = new Predicate()
    {
        public boolean accept(Integer each)
        {
            return each < 3;
        }
    };
    
    Assert.assertEquals(selected, Iterate.select(jdkList, lessThan3));
    Assert.assertEquals(selected, ecList.select(lessThan3));
    

    Here are some alternatives to filtering JDK lists and Eclipse Collections MutableLists using the Predicates factory.

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

    Here is a version that doesn't allocate an object for the predicate, by using the Predicates2 factory instead with the selectWith method that takes a Predicate2.

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

    Sometimes you want to filter on a negative condition. There is a special method in Eclipse Collections for that called reject.

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

    The method partition will return two collections, containing the elements selected by and rejected by the Predicate.

    PartitionIterable jdkPartitioned = Iterate.partition(jdkList, lessThan3);
    Assert.assertEquals(selected, jdkPartitioned.getSelected());
    Assert.assertEquals(rejected, jdkPartitioned.getRejected());
    
    PartitionList ecPartitioned = gscList.partition(lessThan3);
    Assert.assertEquals(selected, ecPartitioned.getSelected());
    Assert.assertEquals(rejected, ecPartitioned.getRejected());
    

    Note: I am a committer for Eclipse Collections.

提交回复
热议问题