Code Fix

上級

stream has already been operated upon の原因と直し方

Streamは1回しか終端操作できません。中間操作の遅延評価も合わせて解説します。

エラーメッセージの読み方

Exception in thread "main" java.lang.IllegalStateException:
main
スレッド名 — mainなら起動直後の処理で発生しています
java.lang
パッケージ — java.lang なら標準の基本例外です
IllegalStateException
例外クラス — 何が起きたか。ここを検索するのが最短です

このエラーが出る典型パターン

パターン1

 1  import java.util.List;
 2  import java.util.stream.Stream;
 3  
 4  public class Main {
 5      public static void main(String[] args) {
 6          Stream<Integer> s = List.of(1, 2, 3).stream();
 7          System.out.println(s.count());
 8          System.out.println(s                        .count());
                                           ^
 9      }
10  }
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closedexited with code 1

Streamは1回しか終端操作できません。使い回さず、必要なたびに作り直します。

直し方: sList.of(1, 2, 3).stream() にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  import java.util.List;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          List<Integer> r = List.of(1, 2, 3).stream()
 6              .filter(n -> n > 1)
 7              .toList   ;
                     ^
 8          System.out.println(r);
 9      }
10  }
Main.java:7: error: cannot find symbol symbol: variable toList

toListはメソッドなので括弧が要ります。古い書き方では collect(Collectors.toList()) を使います。

直し方: toListtoList() にします。

この問題を解いてみる →

パターン3

 1  import java.util.List;
 2  
 3  public class Main {
 4      public static void main(String[] args) {
 5          List.of(1, 2, 3).stream().filter(n -> n > 1)                             ;
                                                                      ^
 6          System.out.println("done");
 7      }
 8  }
出力: done のみ(filterは中間操作なので何も起きません)

中間操作は終端操作が呼ばれるまで実行されません。これを遅延評価と呼びます。

直し方: (空).forEach(System.out::println) にします。

この問題を解いてみる →

よくある誤解

変数に入れると再利用したくなりますが、Streamは使い捨てです。コレクションとは性質が違います。

まとめ

stream has already been operated uponは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)