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