“ストリームはすでに操作されているか終了しています” Javaでの例外

「ストリームはすでに操作またはクローズされています」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の完全なソースコードとすべてのコードスニペットを見つけることができます。