What is the best way to filter a Java Collection?

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

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

相关标签:
27条回答
  • 2020-11-21 07:23

    Since java 9 Collectors.filtering is enabled:

    public static <T, A, R>
        Collector<T, ?, R> filtering(Predicate<? super T> predicate,
                                     Collector<? super T, A, R> downstream)
    

    Thus filtering should be:

    collection.stream().collect(Collectors.filtering(predicate, collector))
    

    Example:

    List<Integer> oddNumbers = List.of(1, 19, 15, 10, -10).stream()
                .collect(Collectors.filtering(i -> i % 2 == 1, Collectors.toList()));
    
    0 讨论(0)
  • 2020-11-21 07:24

    Use CollectionUtils.filter(Collection,Predicate), from Apache Commons.

    0 讨论(0)
  • 2020-11-21 07:24

    Consider Google Collections for an updated Collections framework that supports generics.

    UPDATE: The google collections library is now deprecated. You should use the latest release of Guava instead. It still has all the same extensions to the collections framework including a mechanism for filtering based on a predicate.

    0 讨论(0)
  • 2020-11-21 07:25

    With the ForEach DSL you may write

    import static ch.akuhn.util.query.Query.select;
    import static ch.akuhn.util.query.Query.$result;
    import ch.akuhn.util.query.Select;
    
    Collection<String> collection = ...
    
    for (Select<String> each : select(collection)) {
        each.yield = each.value.length() > 3;
    }
    
    Collection<String> result = $result();
    

    Given a collection of [The, quick, brown, fox, jumps, over, the, lazy, dog] this results in [quick, brown, jumps, over, lazy], ie all strings longer than three characters.

    All iteration styles supported by the ForEach DSL are

    • AllSatisfy
    • AnySatisfy
    • Collect
    • Counnt
    • CutPieces
    • Detect
    • GroupedBy
    • IndexOf
    • InjectInto
    • Reject
    • Select

    For more details, please refer to https://www.iam.unibe.ch/scg/svn_repos/Sources/ForEach

    0 讨论(0)
  • 2020-11-21 07:26

    I wrote an extended Iterable class that support applying functional algorithms without copying the collection content.

    Usage:

    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);
    }
    

    The code above will actually execute

    for( int n : myList )
    {
        if( n % 2 == 0 ) 
        {
            System.out.println(n);
        }
    }
    
    0 讨论(0)
  • 2020-11-21 07:27

    The simple pre-Java8 solution:

    ArrayList<Item> filtered = new ArrayList<Item>(); 
    for (Item item : items) if (condition(item)) filtered.add(item);
    

    Unfortunately this solution isn't fully generic, outputting a list rather than the type of the given collection. Also, bringing in libraries or writing functions that wrap this code seems like overkill to me unless the condition is complex, but then you can write a function for the condition.

    0 讨论(0)
提交回复
热议问题