Java Stream APIについて
Java Stream APIは、Java 8で導入された機能で、コレクションや配列などのデータソースを操作するための強力なツールです。このページでは、Java Streamについて詳細に解説し、具体例を通じてその使い方を説明します。
Streamとは何か
Streamは、データソース(コレクション、配列など)に対して一連の操作を行う抽象的なフレームワークです。従来のループ処理を置き換えることで、簡潔で読みやすいコードを書くことができます。
Stream APIの特徴は次の通りです。
- データ処理を宣言的に記述できる。
- データソースを変更せず、処理結果を新しいデータとして返す。
- 効率的な操作が可能で、必要な要素だけを計算する「遅延評価」をサポート。
Streamの特徴
Streamには以下のような特徴があります。
- 非破壊的操作: Streamは元のデータソースを変更しません。
- 遅延評価: 中間操作は即時実行されず、終端操作が呼び出されたときに実行されます。
- 一回限りの使用: Streamは一度消費すると再利用できません。
Streamの作成方法
Streamは主に以下の方法で作成できます。
- コレクションから作成
- 配列から作成
- 生成メソッドを使用
- ファイルやI/Oデータから作成
コレクションから作成
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "cherry");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
}
}
配列から作成
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
String[] array = {"apple", "banana", "cherry"};
Stream<String> stream = Stream.of(array);
stream.forEach(System.out::println);
}
}
生成メソッドを使用
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream<Integer> stream = Stream.iterate(0, n -> n + 1).limit(10);
stream.forEach(System.out::println);
}
}
Streamの操作(中間操作と終端操作)
Streamの操作は、中間操作と終端操作に分けられます。
中間操作
- filter: 条件に合う要素を選択
- map: 要素を別の形に変換
- sorted: 要素を並べ替え
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list = Arrays.asList("apple", "banana", "cherry");
list.stream()
.filter(s -> s.startsWith("a"))
.map(String::toUpperCase)
.forEach(System.out::println);
}
}
終端操作
- forEach: 各要素に対して処理を実行
- collect: 結果をリストやマップに収集
- reduce: 要素を集約
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream()
.reduce(0, Integer::sum);
System.out.println("Sum: " + sum);
}
}
使用例
例1: 数値のリストをフィルタリングしてソート
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(5, 3, 8, 1, 2);
numbers.stream()
.filter(n -> n > 3)
.sorted()
.forEach(System.out::println);
}
}
例2: テキストデータの処理
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> words = Arrays.asList("stream", "java", "api", "example");
long count = words.stream()
.filter(word -> word.length() > 4)
.count();
System.out.println("Count: " + count);
}
}
並列Streamの使用
Streamは並列処理を簡単に実現する方法を提供します。並列Streamを使用することで、大量のデータを複数のスレッドで効率的に処理できます。
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.parallelStream()
.map(n -> n * n)
.forEach(System.out::println);
}
}
並列Streamは多くのスレッドを使用するため、スレッド安全でない操作や順序が重要な操作では注意が必要です。