質問の背景:
Stream APIは、Java 8に追加され、関数型プログラミングやコレクションの並列処理を容易にするために設計されました。これは、ラムダ式を通じてデータに対する操作のチェーンを記述するための便利な方法を提供します。
問題:
Stream APIがない場合、コレクションのフィルタリング、ソート、集約のために冗長な命令型コードを書く必要がありました。エラーの可能性、メンテナンスの複雑さ、手動での並列処理を試みる際の非効率の問題がありました。
解決策:
Stream APIは、中間操作(intermediate)と終端操作(terminal)からなるパイプラインを構築することを可能にします。ストリームは遅延的で、データを直列または並列で処理し、コードはよりコンパクトで表現力豊かになります。
コレクションの処理の例:
List<String> names = Arrays.asList("アンナ", "イワン", "ペトル", "エヴァ"); names.stream() .filter(s -> s.length() > 3) .map(String::toUpperCase) .sorted() .forEach(System.out::println);
主な特徴:
parallelStream())、ただしコレクションや関数のスレッドセーフ性を考慮する必要があります。閉じたStreamを再利用することはできますか?
いいえ、閉じたStreamを再利用しようとするとIllegalStateExceptionがスローされます。ストリームは一度きりです。
Streamが作成された後に元のコレクションを変更することは影響しますか?
はい、Streamが作成された後、しかし終端操作の前にコレクションが変更されると、ConcurrentModificationExceptionが発生する可能性があります。
Stream操作内で外部の変更可能な変数を使用することはできますか?
推奨されません。並列ストリームでは予期しないエラーが発生する可能性があります。ストリームパイプラインで可変の副作用を避けるのが良いでしょう。
.parallelStream()を適用することプログラマがStreamを介して外部リストを変更するメソッドを呼び出す — これは直列実行時には機能しますが、並列実行時にはデータ構造の破損を引き起こします。
プラス:
マイナス:
パイプライン全体がクリーンに構築されます:操作に副作用がなく、不変コレクションのみが使用され、最終結果はコレクタを介して収集されます。
プラス:
マイナス: