實際上它最初的設計與你的建議相似。請參閱項目lambda存儲庫中的the early implementation(makeResult
現在爲supplier
)。這是後來updated到目前的設計。我相信,這種更新的基本原理是簡化收集器組合器。我沒有找到有關此主題的任何具體討論,但我的猜測得到了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
也受益於當前的設計。
是關於OOP和結構一致的,只是簡單的猜測。 – PSo
請注意,您可以實現適應第二種模式的抽象基類。 – Thilo
@Thilo我認爲第一和第二模式都可以在每個方向進行調整。我只是覺得第二個更直觀。 – popcorny