src/share/classes/java/util/stream/Collectors.java

Print this page
rev 7827 : 8019401: Collectors.collectingAndThen
Reviewed-by:
Contributed-by: brian.goetz@oracle.com

*** 352,361 **** --- 352,398 ---- downstream.combiner(), downstream.finisher(), downstream.characteristics()); } /** + * Adapts a {@code Collector} to perform an additional finishing + * transformation. For example, one could adapt the {@link #toList()} + * collector to always produce an immutable list with: + * <pre>{@code + * List<String> people + * = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList)); + * }</pre> + * + * @param <T> the type of the input elements + * @param <A> intermediate accumulation type of the downstream collector + * @param <R> result type of the downstream collector + * @param <RR> result type of the resulting collector + * @param downstream a collector + * @param finisher a function to be applied to the final result of the downstream collector + * @return a collector which performs the action of the downstream collector, + * followed by an additional finishing step + */ + public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, + Function<R,RR> finisher) { + Set<Collector.Characteristics> characteristics = downstream.characteristics(); + if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) { + if (characteristics.size() == 1) + characteristics = Collectors.CH_NOID; + else { + characteristics = EnumSet.copyOf(characteristics); + characteristics.remove(Collector.Characteristics.IDENTITY_FINISH); + characteristics = Collections.unmodifiableSet(characteristics); + } + } + return new CollectorImpl<>(downstream.supplier(), + downstream.accumulator(), + downstream.combiner(), + downstream.finisher().andThen(finisher), + characteristics); + } + + /** * Returns a {@code Collector} accepting elements of type {@code T} that * counts the number of input elements. If no elements are present, the * result is 0. * * @implSpec