实际上,它最初的设计与您提出的类似。请参阅项目 lambda 存储库中的早期实现(现在是 )。它后来更新为当前设计。我相信,这种更新的基本原理是简化收集器组合器。我没有找到关于这个主题的任何具体讨论,但我的猜测得到了收集器出现在同一个变更集中的事实的支持。考虑以下各项的实现: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);
}
这里只是更改,但原始 ,并且被使用。正如每个元素所要求的那样,减少间接寻址可能非常重要。尝试重写并使用您提出的设计,您将看到问题。新的JDK-9收集器喜欢并从当前的设计中受益。finisher
supplier
accumulator
combiner
accumulator
mapping
collectingAndThen
filtering
flatMapping