実際の Java 8 の作成者は、次のクラスを記述します。
class ToListCollector<T> implements Collector<T, List<T>, List<T>> {
@Override
public Supplier<List<T>> supplier() {
return ArrayList::new;
}
@Override
public BiConsumer<List<T>, T> accumulator() {
return List::add;
}
@Override
public BinaryOperator<List<T>> combiner() {
return (l1, l2) -> {
l1.addAll(l2);
return l1;
};
}
@Override
public Function<List<T>, List<T>> finisher() {
return Function.identity();
}
@Override
public Set<Characteristics> characteristics() {
return Collections.unmodifiableSet(EnumSet.of(Characteristics.IDENTITY_FINISH, Characteristics.CONCURRENT));
}
}
それから彼は Characteristic enum の異なる値が何を意味するかについて話します。そして、彼が書いたこのコレクターが IDENTITY_FINISH および CONCURRENT であり、UNORDERED ではない理由を次のように説明しています。
これまでに開発された ToListCollector は IDENTITY_FINISH です。これは、ストリーム内の要素を蓄積するために使用されるリストが既に期待される最終結果であり、それ以上の変換を必要としないためです。この順序を結果のリストに保持したい。最後に、これは CONCURRENT ですが、先ほど述べたように、ストリームは、基になるデータ ソースが順序付けされていない場合にのみ並列で処理されます。
基になるソースが順序付けされていない場合にのみストリームが並列処理されるのはなぜですか? まだ並行して処理されると思いますが、combiner() は順序を維持する必要があります。本の間違いですか?
Brian Goetz は、この投稿の最後のパラグラフで、順序付けられたストリームの並列処理について非常に明確に述べていると思います。
本のページ数は 192 ~ 193 です。