"Stream wurde bereits bearbeitet oder geschlossen" Ausnahme in Java

1. Überblick

In diesem kurzen Artikel werden wir eine allgemeine Exception erörtern, die beim Arbeiten mit der Stream -Klasse in Java 8 auftreten kann:

IllegalStateException: stream has already been operated upon or closed.

Wir werden die Szenarien, in denen diese Ausnahmebedingung auftritt, und die möglichen Möglichkeiten, dies zu vermeiden, zusammen mit praktischen Beispielen aufdecken.

2. Die Ursache

In Java 8 repräsentiert jede Stream -Klasse eine Datensequenz zum einmaligen Gebrauch und unterstützt mehrere E/A-Vorgänge.

~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ nur einmal an (mit einem Aufruf-Vorgang) nur einmal ausgeführt werden sollte. Eine Stream-Implementierung kann IllegalStateException auslösen, wenn sie feststellt, dass der Stream erneut verwendet wird.

Immer wenn eine Terminaloperation für ein Stream -Objekt aufgerufen wird, wird die Instanz verbraucht und geschlossen.

Daher dürfen wir nur eine einzige Operation ausführen, die einen Stream ** verbraucht. Andernfalls wird eine Ausnahme angezeigt, dass der Stream__ bereits bearbeitet oder geschlossen wurde.

Mal sehen, wie dies in ein praktisches Beispiel übersetzt werden kann:

Stream<String> stringStream = Stream.of("A", "B", "C", "D");
Optional<String> result1 = stringStream.findAny();
System.out.println(result1.get());
Optional<String> result2 = stringStream.findFirst();

Als Ergebnis:

A
Exception in thread "main" java.lang.IllegalStateException:
  stream has already been operated upon or closed

Nachdem die # findAny () - Methode aufgerufen wurde, wird stringStream geschlossen. Daher wird jeder weitere Vorgang auf Stream die IllegalStateException auslösen. Dies ist der Fall, nachdem die # findFirst () - Methode aufgerufen wurde.

=== 3. Die Lösung

Einfach ausgedrückt, besteht die Lösung darin, jedes Mal, wenn wir einen neuen Stream brauchen, einen neuen Stream zu erstellen.

Natürlich können wir das auch manuell tun, aber das Supplier -Funktionsinterface ist wirklich praktisch:

Supplier<Stream<String>> streamSupplier
  = () -> Stream.of("A", "B", "C", "D");
Optional<String> result1 = streamSupplier.get().findAny();
System.out.println(result1.get());
Optional<String> result2 = streamSupplier.get().findFirst();
System.out.println(result2.get());

Als Ergebnis:

A
A

Wir haben das streamSupplier -Objekt mit dem Typ Stream <String> definiert, der genau derselbe Typ ist, den die # get () -Methode zurückgibt. Der Supplier basiert auf einem Lambda-Ausdruck, der keine Eingabe übernimmt und einen neuen Stream zurückgibt.

Das Aufrufen der funktionalen Methode get () auf dem Supplier gibt ein neu erstelltes Stream -Objekt zurück, auf dem wir eine weitere Stream -Operation sicher ausführen können.

=== 5. Fazit

In diesem kurzen Lernprogramm haben wir gesehen, wie Terminaloperationen an einem Stream mehrmals ausgeführt werden, während die berühmte IllegalStateException vermieden wird, die ausgelöst wird, wenn der Stream bereits geschlossen oder bearbeitet wird.

Den vollständigen Quellcode und alle Codeausschnitte für diesen Artikel finden Sie unter over auf GitHub .