,我被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