,我被JDK-8望着Collectors.toSet
實施和幾乎看到了明顯的事情:Collectors.toSet實現細節
public static <T> Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>(
(Supplier<Set<T>>) HashSet::new,
Set::add,
(left, right) -> { left.addAll(right); return left; }, // combiner
CH_UNORDERED_ID);
看那combiner
片刻;這已經在here之前討論過了,但主意是a combiner folds from the second argument into the first
。這顯然發生在這裏。
但後來我看着jdk-9
實施和看到這個:
public static <T> Collector<T, ?, Set<T>> toSet() {
return new CollectorImpl<>(
(Supplier<Set<T>>) HashSet::new,
Set::add,
(left, right) -> {
if (left.size() < right.size()) {
right.addAll(left); return right;
} else {
left.addAll(right); return left;
}
},
CH_UNORDERED_ID);
現在爲什麼出現這種情況是有點明顯 - 它需要較少的時間來補充less elements to a bigger Set, then the other way around
。但是真的比簡單的addAll
便宜,考慮分支的額外開銷呢?
而且這打破我的法律約總是摺疊離開......
有人可以提供一些線索嗎?
我不知道我理解你的問題。您已經瞭解了'jdk-9'實現的性能原理。爲什麼你會期望如果導致效率低得多的程序,你的這部法律得到維護? – gyre
我不確定你的法律是否反映在這個答案中。沒有指定關於摺疊*左*一致,尤其是在接受的答案,這給出了有序與無序流的區別。 – gyre
@gyre你可能是對的..似乎有點匆忙的問題。 – Eugene