Stream a collection and collect into multiple results depending on independent predicates

前端 未结 2 2028
天涯浪人
天涯浪人 2020-12-16 05:27

I am staring at some imperative code which I am trying to convert to a purely functional style. Basically there is a iterative for-loop over inputSet in which

2条回答
  •  伪装坚强ぢ
    2020-12-16 05:46

    Another approach would be to use the Consumer.andThen(anotherConsumer) method to create a composed consumer made of inner consumers that execute in sequence. Each one of these inner consumers would test every predicate and classify elements depending on whether they match or not.

    public static  Consumer classify(Predicate predicate, Consumer action) {
        return elem -> Optional.ofNullable(elem)
            .filter(predicate)
            .ifPresent(action);
    }
    

    This utility method returns a consumer that will execute the given action on the element being consumed, as long as the predicate returns true for the element.

    Test:

    Stream stream = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
    
    Set set1 = new LinkedHashSet<>();
    Set set2 = new LinkedHashSet<>();
    Set set3 = new LinkedHashSet<>();
    
    // Here's the composed consumer, made of inner consumers
    Consumer multiClassifier = classify(n -> n % 2 == 0, set1::add)
            .andThen(classify(n -> n % 3 == 0, set2::add))
            .andThen(classify(n -> n % 5 == 0, set3::add));
    
    // Here the stream is consumed by the composed consumer
    stream.forEach(multiClassifier);
    

    Each inner consumer is created with the utility method defined above, which receives an independent predicate that, when matched, will add the element of the stream to the given set, i.e. if the element of the stream is a multiple of 3, it will be added to set2.

    At the end, the stream is consumed with this composed consumer and thus the stream is classified by independent predicates:

    System.out.println(set1); // [2, 4, 6, 8, 10, 12]
    System.out.println(set2); // [3, 6, 9, 12]
    System.out.println(set3); // [5, 10]
    

提交回复
热议问题