jdk/src/java.base/share/classes/java/util/stream/Collectors.java
changeset 34685 ababd79c3b2b
parent 32755 6e8998981fbd
child 36654 c48e75478177
equal deleted inserted replaced
34684:b721350c05c0 34685:ababd79c3b2b
   432      * returns a stream of results
   432      * returns a stream of results
   433      * @param downstream a collector which will receive the elements of the
   433      * @param downstream a collector which will receive the elements of the
   434      * stream returned by mapper
   434      * stream returned by mapper
   435      * @return a collector which applies the mapping function to the input
   435      * @return a collector which applies the mapping function to the input
   436      * elements and provides the flat mapped results to the downstream collector
   436      * elements and provides the flat mapped results to the downstream collector
   437      * @since 1.9
   437      * @since 9
   438      */
   438      */
   439     public static <T, U, A, R>
   439     public static <T, U, A, R>
   440     Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
   440     Collector<T, ?, R> flatMapping(Function<? super T, ? extends Stream<? extends U>> mapper,
   441                                    Collector<? super U, A, R> downstream) {
   441                                    Collector<? super U, A, R> downstream) {
   442         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
   442         BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
   447                                         result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
   447                                         result.sequential().forEach(u -> downstreamAccumulator.accept(r, u));
   448                                 }
   448                                 }
   449                             },
   449                             },
   450                             downstream.combiner(), downstream.finisher(),
   450                             downstream.combiner(), downstream.finisher(),
   451                             downstream.characteristics());
   451                             downstream.characteristics());
       
   452     }
       
   453 
       
   454     /**
       
   455      * Adapts a {@code Collector} to one accepting elements of the same type
       
   456      * {@code T} by applying the predicate to each input element and only
       
   457      * accumulating if the predicate returns {@code true}.
       
   458      *
       
   459      * @apiNote
       
   460      * The {@code filtering()} collectors are most useful when used in a
       
   461      * multi-level reduction, such as downstream of a {@code groupingBy} or
       
   462      * {@code partitioningBy}.  For example, given a stream of
       
   463      * {@code Employee}, to accumulate the employees in each department that have a
       
   464      * salary above a certain threshold:
       
   465      * <pre>{@code
       
   466      *     Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
       
   467      *         = employees.stream().collect(groupingBy(Employee::getDepartment,
       
   468      *                                              filtering(e -> e.getSalary() > 2000, toSet())));
       
   469      * }</pre>
       
   470      * A filtering collector differs from a stream's {@code filter()} operation.
       
   471      * In this example, suppose there are no employees whose salary is above the
       
   472      * threshold in some department.  Using a filtering collector as shown above
       
   473      * would result in a mapping from that department to an empty {@code Set}.
       
   474      * If a stream {@code filter()} operation were done instead, there would be
       
   475      * no mapping for that department at all.
       
   476      *
       
   477      * @param <T> the type of the input elements
       
   478      * @param <A> intermediate accumulation type of the downstream collector
       
   479      * @param <R> result type of collector
       
   480      * @param predicate a predicate to be applied to the input elements
       
   481      * @param downstream a collector which will accept values that match the
       
   482      * predicate
       
   483      * @return a collector which applies the predicate to the input elements
       
   484      * and provides matching elements to the downstream collector
       
   485      * @since 9
       
   486      */
       
   487     public static <T, A, R>
       
   488     Collector<T, ?, R> filtering(Predicate<? super T> predicate,
       
   489                                Collector<? super T, A, R> downstream) {
       
   490         BiConsumer<A, ? super T> downstreamAccumulator = downstream.accumulator();
       
   491         return new CollectorImpl<>(downstream.supplier(),
       
   492                                    (r, t) -> {
       
   493                                        if (predicate.test(t)) {
       
   494                                            downstreamAccumulator.accept(r, t);
       
   495                                        }
       
   496                                    },
       
   497                                    downstream.combiner(), downstream.finisher(),
       
   498                                    downstream.characteristics());
   452     }
   499     }
   453 
   500 
   454     /**
   501     /**
   455      * Adapts a {@code Collector} to perform an additional finishing
   502      * Adapts a {@code Collector} to perform an additional finishing
   456      * transformation.  For example, one could adapt the {@link #toList()}
   503      * transformation.  For example, one could adapt the {@link #toList()}