
JavaのStream APIをマスターして、データ処理を自由自在に操ろう!🚀
Java Stream APIとは?基本概念を理解しよう
Java 8で導入されたStream APIは、コレクションなどのデータソースに対して、宣言的に一連の操作を適用し、効率的なデータ処理を可能にする強力なツールです。従来のループ処理と比較して、コードが簡潔になり、並列処理も容易になるため、パフォーマンス向上にも貢献します。
Stream APIは、データソース(コレクション、配列など)からStreamを作成し、中間操作(filter, map, sortedなど)を適用してStreamを変換し、最後に終端操作(forEach, collect, reduceなど)で結果を得るという流れで処理を行います。
Streamはデータソースを変更せず、新しいStreamを生成する点が特徴です。これにより、元のデータを安全に保ちながら、様々なデータ処理を行うことができます。
Stream APIの主要な操作:中間操作と終端操作
Stream APIの操作は大きく分けて、中間操作と終端操作の2種類があります。
中間操作: Streamを変換する操作です。複数の中間操作を連結して、パイプラインを構築できます。中間操作は、Streamを返すため、連続して呼び出すことが可能です。代表的な中間操作には、filter
, map
, sorted
, distinct
, limit
, skip
などがあります。
終端操作: Streamから結果を取り出す操作です。終端操作を実行すると、Streamの処理が開始されます。終端操作は、Streamを返さないため、パイプラインの最後に記述します。代表的な終端操作には、forEach
, collect
, reduce
, count
, anyMatch
, allMatch
, noneMatch
, findFirst
, findAny
などがあります。
以下に、中間操作と終端操作の例を示します。
List names = Arrays.asList("Alice", "Bob", "Charlie", "David", "Eve");
// 長さが5文字の名前をフィルタリングし、大文字に変換して出力
names.stream()
.filter(name -> name.length() == 5)
.map(String::toUpperCase)
.forEach(System.out::println); // 出力: ALICE, CHARLIE
上記の例では、filter
とmap
が中間操作、forEach
が終端操作です。
Filter:条件に合致する要素を抽出
filter
メソッドは、指定された条件(Predicate)を満たす要素のみを抽出します。
List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 偶数のみを抽出
List evenNumbers = numbers.stream()
.filter(number -> number % 2 == 0)
.collect(Collectors.toList());
System.out.println(evenNumbers); // 出力: [2, 4, 6, 8, 10]
filter
メソッドに渡すPredicateは、引数を受け取りboolean値を返す関数型インタフェースです。
Map:要素を別の型に変換
map
メソッドは、Streamの各要素を指定された関数(Function)によって別の要素に変換します。
List names = Arrays.asList("Alice", "Bob", "Charlie");
// 各名前の長さを取得
List nameLengths = names.stream()
.map(String::length)
.collect(Collectors.toList());
System.out.println(nameLengths); // 出力: [5, 3, 7]
map
メソッドに渡すFunctionは、引数を受け取り別の型の値を返す関数型インタフェースです。
Collect:Streamの結果をコレクションに変換
collect
メソッドは、Streamの処理結果をListやSetなどのコレクションに変換します。
List numbers = Arrays.asList(1, 2, 3, 4, 5);
// Streamの結果をListに変換
List numberList = numbers.stream().collect(Collectors.toList());
// Streamの結果をSetに変換
Set numberSet = numbers.stream().collect(Collectors.toSet());
System.out.println(numberList); // 出力: [1, 2, 3, 4, 5]
System.out.println(numberSet); // 出力: [1, 2, 3, 4, 5] (順序は保証されません)
Collectors
クラスには、toList()
, toSet()
, toMap()
, joining()
など、様々な変換メソッドが用意されています。
Reduce:要素をまとめて単一の結果を生成
reduce
メソッドは、Streamの要素を結合して単一の結果を生成します。例えば、数値の合計や文字列の連結などに使用できます。
List numbers = Arrays.asList(1, 2, 3, 4, 5);
// 数値の合計を計算
Optional sum = numbers.stream().reduce(Integer::sum);
System.out.println(sum.orElse(0)); // 出力: 15
reduce
メソッドは、初期値を指定することも可能です。
List numbers = Arrays.asList(1, 2, 3, 4, 5);
// 数値の合計を計算 (初期値10)
int sumWithInitial = numbers.stream().reduce(10, Integer::sum);
System.out.println(sumWithInitial); // 出力: 25
初期値を指定しない場合は、Optional
で結果が返されます。これは、Streamが空の場合にnull
になることを防ぐためです。
参考リンク
まとめ
Java Stream APIは、データ処理を効率化するための強力なツールです。filter
, map
, collect
, reduce
などの基本的な操作を理解することで、より簡潔で読みやすいコードを書くことができます。ぜひStream APIを活用して、データ処理の効率化を目指してください。