Stream APIとは
配列やコレクションに対して、値の集計や変換などの処理ができるAPIのこと。主に以下の3つのステージで構成される。
- 生成(streamの生成)
- 中間操作(要素に対する処理)
- 終端操作(結果を出力)
ストリームの生成
コレクションから生成
List<String> list = Arrays.asList("A", "B", "C");
Stream<String> stream = list.stream();
配列から生成
Stream<Integer> arrayStream = Arrays.stream(new Integer[]{1, 2, 3});
静的メソッドを使用
Stream<String> generatedStream = Stream.of("X", "Y", "Z");
中間操作
中間操作はストリームを加工・変換するための操作で、これらは終端操作が呼ばれるまで実行されない。主なメソッドは以下。
filter
条件に合う要素だけを残す。
stream.filter(s -> s.startsWith("A"))
map
各要素を別の要素に変換
stream.map(String::toUpperCase)
flatMap
ネストしたストリームを平坦化
stream.flatMap(List::stream)
distinct
重複を排除
stream.distinct()
sorted
ソートされたストリームを生成
stream.sorted()
limit
指定した数までの要素を取得
stream.limit(5)
skip
指定した数だけスキップ
stream.skip(3)
終端操作
ストリームを閉じ、結果を生成する。
collect
結果をコレクションや文字列に変換
stream.collect(Collectors.toList())
forEach
各要素に対して処理を実行
stream.forEach(System.out::println)
reduce
要素を1つの値に畳み込む
stream.reduce(0,Integer::sum)
count
要素数をカウント
stream.count()
anyMatch
条件を満たす要素が存在するかチェック
stream.anyMatch(s -> s.contains("A"))
noneMatch
条件を満たす要素が1つもないかチェック
stream.noneMatch(s -> s.isEmpty())
findFirst
最初の要素を取得
stream.findFirst()
findAny
任意の要素を取得
stream.findAny()
ストリームAPIの特性
-
遅延評価
中間操作は終端操作が呼び出されるまで評価されない。これにより、効率的な処理が可能。 -
無変更性
ストリームは元のデータを変更しない。 -
一度限りの使用
ストリームは一度消費されると再利用できない。
注意点
-
並列ストリーム
parallelStreamを使うと並列処理が可能になるが、データサイズや特性に応じて慎重に選択する必要がある。list.parallelStream().forEach(System.out::println);
-
状態を持たない操作
中間操作は状態を持たないことが推奨される。 -
終端操作の結果
終端操作の結果がvoidなのか、値を返すのか意識しておくこと。 -
ストリームと例外
ラムダ式で例外を扱う場合、エラーハンドリングの実装について意識しておくこと。