PR

 同様にfindFirstメソッドも順番に影響を受けます。

 パラレルストリームでは先頭から処理が行われないのですが、findFirstメソッドは必ず先頭を探します。たとえば、リスト4を改造して、始めの偶数を探すようにしてみましょう。

リスト5 始めの偶数を探索

        IntStream.range(0, 10)
                 .parallel()
                 .filter(x -> x%2 == 0)
                 .findFirst()
                 .ifPresent(System.out::println);

 このコードを実行すると、当然ですが必ず0を出力します。

 もし、単に偶数があるかどうかをチェックするためにfindFirstメソッドを使用しているのであるとすれば、パラレルストリームではfindFirstメソッドではなくfindAnyメソッドを使用します。

 リスト5のfindFirstメソッドをfindAnyメソッドに置き換えてみましょう。実行すると、そのたびに出力される偶数は異なるはずです。しかし、単に偶数があるかどうかをチェックするだけであれば、これで十分です。

 なお、toArrayメソッドや、collectメソッドの引数にCollectors.toListメソッドを使用した場合、順序は保存されます。つまり、リスト6を実行すると、配列evensは必ず[0, 2, 4, 6, 8]になります。

リスト6 偶数の配列を生成

        int[] evens = IntStream.range(0, 10)
                               .parallel()
                               .filter(x -> x%2 == 0)
                               .toArray();

マップへの変換

 Collectorsクラスにはストリームをマップに変換させるgroupingByメソッドとtoMapメソッドが提供されています。いずれもパラレルストリームで使用することができます。

 しかし、これらのメソッドの代わりにgroupingByConcurrentメソッド、toConcurrentMapメソッドを使用することも可能です。

 groupingByConcurrentメソッドとtoConcurrentMapメソッドはいずれも戻り値の型がjava.util.concurrent.ConcurrentMapインタフェースになります。