Stream API

JavaのStream APIは、Java 8で導入された関数型プログラミングの要素を取り入れた機能で、コレクションなどのデータを宣言的に処理するための手段を提供します。これにより、従来のforループやIteratorによる明示的な処理から解放され、より簡潔で読みやすいコードを書くことが可能になります。


1. Stream APIの概要

Streamは、データの集まりに対して一連の処理(変換・フィルタ・集約など)を流れるように実行できる仕組みです。コレクションや配列からStreamを生成し、中間操作を経て、終端操作で結果を得ます。

java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); names.stream() .filter(name -> name.startsWith("A")) .map(String::toUpperCase) .forEach(System.out::println);

上記の例では、”Alice”だけが条件に一致し、大文字に変換されて出力されます。


2. Streamの特徴

  • 宣言的な記述:処理の「何をするか」に焦点を当て、「どうするか」を抽象化。

  • 中間操作と終端操作の分離

    • 中間操作(filter、mapなど):Streamを返す(遅延評価)。

    • 終端操作(forEach、collect、countなど):計算を実行し、値を返す。

  • 一度限りの使用:Streamは一度使うと再利用できません(消費される)。

  • 非破壊的:元のコレクションを変更せず、新しいデータに変換。

  • パイプライン処理:複数の処理を連鎖的につなげる。


3. 主な中間操作

操作 説明
filter() 条件に一致する要素のみを通過させる
map() 要素を別の形に変換する(例:大文字変換)
sorted() 要素をソートする
distinct() 重複を排除する
limit() 指定数の要素に制限する
skip() 指定数の要素をスキップする

4. 主な終端操作

操作 説明
forEach() 各要素に対して処理を実行する
collect() 結果をList、Set、Mapなどに収集する
count() 要素数を返す
anyMatch() いずれかが条件を満たすか判定
allMatch() すべてが条件を満たすか判定
findFirst() 最初の要素を取得する

5. 並列処理:parallelStream()

Streamはデフォルトでは順次処理ですが、parallelStream()を使用することでマルチスレッド処理を容易に実現できます。

java
list.parallelStream() .filter(...) .map(...) .forEach(...);

ただし、並列処理は順序が保証されず、副作用のある操作には注意が必要です。


6. Stream APIの利点と注意点

利点

  • コードが簡潔で読みやすくなる

  • 関数型スタイルにより、バグが少なくなる

  • 並列処理が簡単に導入できる

注意点

  • 遅延評価の理解が必要

  • 一度使用したStreamは再利用不可

  • パフォーマンスが常に良いわけではない(並列処理時は要検証)


まとめ

Stream APIは、コレクション操作の表現力を大幅に向上させ、宣言的・関数型スタイルによるデータ処理を可能にします。Javaにおけるモダンな書き方として、従来のループ処理からの置き換えが進んでおり、特に読みやすさ・保守性・テストのしやすさを重視する場面で非常に有効です。

生成日:2025/05/03