「ストリームはすでに操作またはクローズされています」Javaの例外
1. 概要
この短い記事では、Java 8でStreamクラスを操作するときに発生する可能性のある一般的なExceptionについて説明します。
IllegalStateException: stream has already been operated upon or closed.
この例外が発生した場合のシナリオと、それを回避するための可能な方法を、実際の例とともに説明します。
2. 原因
Java 8では、各Streamクラスは、データの1回限りのシーケンスを表し、複数のI / O操作をサポートします。
Streamは、1回だけ操作する必要があります(中間またはターミナルストリーム操作を呼び出す)。 Stream実装は、Streamが再利用されていることを検出すると、IllegalStateExceptionをスローする場合があります。
Streamオブジェクトで端末操作が呼び出されるたびに、インスタンスは消費されて閉じられます。
したがって、we’re only allowed to perform a single operation that consumes a*Stream*,以外の場合は、Streamがすでに操作されているか、閉じられていることを示す例外が発生します。
これを実際の例に変換する方法を見てみましょう。
Stream stringStream = Stream.of("A", "B", "C", "D");
Optional result1 = stringStream.findAny();
System.out.println(result1.get());
Optional result2 = stringStream.findFirst();
結果として:
A
Exception in thread "main" java.lang.IllegalStateException:
stream has already been operated upon or closed
#findAny()メソッドが呼び出された後、stringStreamは閉じられます。したがって、Streamをさらに操作すると、IllegalStateExceptionがスローされます。これは、IllegalStateExceptionを呼び出した後に発生したことです。 t4)sメソッド。
3. ソリューション
簡単に言えば、ソリューションは、必要になるたびに新しいStreamを作成することで構成されます。
もちろん、手動で行うこともできますが、Supplierの関数型インターフェースが非常に便利になるのはそのためです。
Supplier> streamSupplier
= () -> Stream.of("A", "B", "C", "D");
Optional result1 = streamSupplier.get().findAny();
System.out.println(result1.get());
Optional result2 = streamSupplier.get().findFirst();
System.out.println(result2.get());
結果として:
A
A
streamSupplierオブジェクトをタイプStream<String>で定義しました。これは、#get()メソッドが返すタイプとまったく同じです。 Supplierは、入力を受け取らず、新しいStreamを返すラムダ式に基づいています。
Supplierで関数メソッドget()を呼び出すと、新しく作成されたStreamオブジェクトが返され、別のStream操作を安全に実行できます。
5. 結論
このクイックチュートリアルでは、Streamがすでに閉じられているか操作されているときにスローされる有名なIllegalStateExceptionを回避しながら、Streamで端末操作を複数回実行する方法を説明しました。
この記事over on GitHubの完全なソースコードとすべてのコードスニペットを見つけることができます。