Ответ 1
На самом деле он был первоначально разработан так же, как вы предлагаете. См. ранняя реализация в репозитории лямбда проекта (makeResult
теперь supplier
). Позднее обновлено до текущего дизайна. Я полагаю, обоснование такого обновления заключается в упрощении коллектора. Я не нашел какой-либо конкретной дискуссии по этой теме, но моя догадка подтверждается тем фактом, что коллекционер mapping
появился в том же наборе изменений. Рассмотрим реализацию Collectors.mapping
:
public static <T, U, A, R>
Collector<T, ?, R> mapping(Function<? super T, ? extends U> mapper,
Collector<? super U, A, R> downstream) {
BiConsumer<A, ? super U> downstreamAccumulator = downstream.accumulator();
return new CollectorImpl<>(downstream.supplier(),
(r, t) -> downstreamAccumulator.accept(r, mapper.apply(t)),
downstream.combiner(), downstream.finisher(),
downstream.characteristics());
}
Эта реализация должна переопределить только функцию accumulator
, оставив supplier
, combiner
и finisher
как есть, поэтому у вас нет дополнительной косвенности при вызове supplier
, combiner
или finisher
: вы просто вызываете непосредственно функции, возвращаемые исходным коллектором. Это еще более важно с collectingAndThen
:
public static<T,A,R,RR> Collector<T,A,RR> collectingAndThen(Collector<T,A,R> downstream,
Function<R,RR> finisher) {
// ... some characteristics transformations ...
return new CollectorImpl<>(downstream.supplier(),
downstream.accumulator(),
downstream.combiner(),
downstream.finisher().andThen(finisher),
characteristics);
}
Здесь изменяется только finisher
, но используются оригинальные supplier
, accumulator
и combiner
. Поскольку accumulator
вызывается для каждого элемента, уменьшение косвенности может быть довольно важным. Попробуйте переписать mapping
и collectingAndThen
с предлагаемым дизайном, и вы увидите проблему. Новые коллекторы JDK-9, такие как filtering
и flatMapping
, также извлекают выгоду из текущего дизайна.