352 downstream.combiner(), downstream.finisher(), |
352 downstream.combiner(), downstream.finisher(), |
353 downstream.characteristics()); |
353 downstream.characteristics()); |
354 } |
354 } |
355 |
355 |
356 /** |
356 /** |
|
357 * Adapts a {@code Collector} to perform an additional finishing |
|
358 * transformation. For example, one could adapt the {@link #toList()} |
|
359 * collector to always produce an immutable list with: |
|
360 * <pre>{@code |
|
361 * List<String> people |
|
362 * = people.stream().collect(collectingAndThen(toList(), Collections::unmodifiableList)); |
|
363 * }</pre> |
|
364 * |
|
365 * @param <T> the type of the input elements |
|
366 * @param <A> intermediate accumulation type of the downstream collector |
|
367 * @param <R> result type of the downstream collector |
|
368 * @param <RR> result type of the resulting collector |
|
369 * @param downstream a collector |
|
370 * @param finisher a function to be applied to the final result of the downstream collector |
|
371 * @return a collector which performs the action of the downstream collector, |
|
372 * followed by an additional finishing step |
|
373 */ |
|
374 public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream, |
|
375 Function<R,RR> finisher) { |
|
376 Set<Collector.Characteristics> characteristics = downstream.characteristics(); |
|
377 if (characteristics.contains(Collector.Characteristics.IDENTITY_FINISH)) { |
|
378 if (characteristics.size() == 1) |
|
379 characteristics = Collectors.CH_NOID; |
|
380 else { |
|
381 characteristics = EnumSet.copyOf(characteristics); |
|
382 characteristics.remove(Collector.Characteristics.IDENTITY_FINISH); |
|
383 characteristics = Collections.unmodifiableSet(characteristics); |
|
384 } |
|
385 } |
|
386 return new CollectorImpl<>(downstream.supplier(), |
|
387 downstream.accumulator(), |
|
388 downstream.combiner(), |
|
389 downstream.finisher().andThen(finisher), |
|
390 characteristics); |
|
391 } |
|
392 |
|
393 /** |
357 * Returns a {@code Collector} accepting elements of type {@code T} that |
394 * Returns a {@code Collector} accepting elements of type {@code T} that |
358 * counts the number of input elements. If no elements are present, the |
395 * counts the number of input elements. If no elements are present, the |
359 * result is 0. |
396 * result is 0. |
360 * |
397 * |
361 * @implSpec |
398 * @implSpec |