私はJDK-8の下Collectors.toSet
実装を見ていたし、ほとんどは明白なことを見た:一瞬combiner
で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);
ルック。これは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
あなたの法律がその回答に反映されているかどうかはわかりません。 * left *を一貫して折りたたむことについては何も指定されていません。特に順序付けされたストリームと順序付けられていないストリームの区別を与える受け入れられた答えには何も指定されていません。 – gyre
@gyreあなたは正しいかもしれない。少し急いで質問するようだ。 – Eugene