【Java】Stream API(ループ)の基本的な使い方

java

Java8でfor文を使ったら負け、ととあるブログで言われていました。
今回はそんなfor文のかわりとなる、Stream APIの基本的な使い方を紹介します。

従来のfor文の替りに、Stream APIを使うことで、forループの処理がスッキリを簡単な記述になります。
for文って、入れ込んできたらどうしてもソースコードが汚れていくものです。
Stream APIの登場でソースコードがキレイに保てるようになればよいなぁと期待しています。

[スポンサーリンク]

従来のfor文とStream APIを比べてみる

こちらは、Listをfor文でループさせる従来のロジックです。

List<String> list = new ArrayList<>();
list.add("list1");
list.add("list2");
list.add("list3");
for (String val : list) {
	System.out.println("value : " + val);
}
>実行結果
value : list1
value : list2
value : list3

こちらは、ListをStream APIでループさせるJava8特有のロジックです。
{}がなくなった分、少しシンプルになりました。

List<String> list = new ArrayList<>();
list.add("list1");
list.add("list2");
list.add("list3");
Stream<String> stream = list.stream();
stream.forEach(e -> System.out.println("value : " + e));
>実行結果
value : list1
value : list2
value : list3

Stream.forEachからメソッドを呼び出す

Stream.forEachの中から、独自で作ったメソッドを呼び出すことも出来ます。

public static void main(String arg[]) {
	List<String> list = new ArrayList<>();
	list.add("list1");
	list.add("list2");
	list.add("list3");

	Stream<String> stream = list.stream();
	stream.forEach(e -> output(e));
}

private static void output(String value) {
	System.out.println("Private メソッドで表示しています! : " + value);
}
>実行結果
Private メソッドで表示しています! : list1
Private メソッドで表示しています! : list2
Private メソッドで表示しています! : list3

IllegalStateExceptionが出た時の対処方

Stream APIを使う時の注意として、使い方を間違えると「java.lang.IllegalStateException: stream has already been operated upon or closed」が出てきます。

IllegalStateExceptionが出てくる原因と対処法について紹介します。
以下のソースを見て下さい。
1つのStreamに対して、2回ループの処理を回すと、1回目のループの処理は正常に動きますが、2回目のループでエラーになります。

1つのStreamに対してループは1度だけにしましょう。
もし2回ループを回したい場合は、2つStreamを用意しましょう。

List<String> list = new ArrayList<>();
list.add("list1");
list.add("list2");
list.add("list3");
Stream<String> stream = list.stream();
stream.forEach(e -> System.out.println("value : " + e));
stream.forEach(e -> System.out.println("value : " + e));
>実行結果
value : list1
value : list2
value : list3
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed

さいごに

従来のFor文だと視覚的にループの処理がわかりやすい反面、煩雑になるリスクもありました。
Stream APIだとコードがだいぶスッキリします。
わたしはStream APIの方が好きです。

ただどうしても、入れ子にしてしまうと、Stream APIを使っても煩雑になるような気がします。。
こればかりはプログラマの腕にかかっているのでしょうね。
永遠の課題「入れ子」には気をつけましょう。
それでは!