それは、ストリームパイプラインが最後のステップ、終了操作によって駆動されていることを理解する価値があります。
代わりのコンベアベルトの下のアイテムをプッシュストリームプロデューサーの思考は、待機消費者に、アイテムを引っ張って終了操作を考える - 尋ねられたときプロデューサーが新しいアイテムを追加します。
例では、終了操作はcollect(collector)
です。これは、前のステップからアイテムがなくなるまでアイテムをプルし、各要素をコレクタに送信します。前のステップでmap()
ですが、それはオンデマンドで動作します - それは唯一のその前段階からアイテムを引っ張る - filter()
からcollect()
は別の項目を要求したとき。
findFirst()
は、別の終了操作です。前の手順でストリームの最初の項目である1つの項目を尋ねます。だから我々はfindFirst()
パイプラインステップは、正確に一度map()
ステップから読み込みます...
list.stream()
.filter(ele -> ele.isBlue())
.map(Element::getSomething)
.findFirst(toList());
...にあなたの例を変更した場合。アイテムを取得すると、Optional.of(item)
が返されます。順番に
map()
は正確に一度filter()
から読み込みます。 filter()
はisBlue()
がtrueになるまでストリームから繰り返し読み込み、それを返します。
filter()
が一致するものを見つけずに入力ストリームの最後に到達すると、ストリームの終わりを示します。これはパイプラインを伝播し、findFirst()
はストリームの終わりに気付き、Optional.empty()
を返します。
も任意一致する項目が返されfindAny()
があります。これは、パイプラインの一部が並列化された場合に速く戻る場合があります。または、パイプラインが順序敏感なステップを持つと並列化される可能性があります。
すべての終了操作を確認するには、Stream
Javadocを参照してください。
'collect'を呼び出す代わりに、findFirst()。orElse(null)'を呼び出します。 'parallelStream'を使用していて、ストリームに要素が1つしかないことが保証されている場合は、' findAny()。orElse(null) 'を代わりに使うことができます。 – Lothar
ストリームは怠惰なので、 'filter(..)。findFirst().Else(..whatever)' –