"Stream is al geopereerd of gesloten" Uitzondering in Java

1. Overzicht

In dit korte artikel gaan we een veel voorkomende bespreken Uitzondering die we kunnen tegenkomen bij het werken met de Stroom klasse in Java 8:

IllegalStateException: stream is al gebruikt of gesloten.

We zullen de scenario's ontdekken wanneer deze uitzondering optreedt, en de mogelijke manieren om deze te vermijden, samen met praktische voorbeelden.

2. De oorzaak

In Java 8, elk Stroom class vertegenwoordigt een reeks gegevens voor eenmalig gebruik en ondersteunt verschillende I / O-bewerkingen.

EEN Stroom mag slechts één keer worden gebruikt (waarbij een tussenliggende of terminale stream-bewerking wordt aangeroepen). Een Stream-implementatie kan gooien IllegalStateException als het detecteert dat het Stroom wordt hergebruikt.

Telkens wanneer een terminaloperatie wordt aangeroepen op een Stroom object, wordt de instantie verbruikt en gesloten.

Daarom we mogen slechts één bewerking uitvoeren die een Stroom, anders krijgen we een uitzondering die stelt dat de Stroom is al geopereerd of gesloten.

Laten we eens kijken hoe dit vertaald kan worden naar een praktisch voorbeeld:

Stream stringStream = Stream.of ("A", "B", "C", "D"); Optioneel resultaat1 = stringStream.findAny (); System.out.println (result1.get ()); Optioneel resultaat2 = stringStream.findFirst ();

Als resultaat:

Een uitzondering in thread "main" java.lang.IllegalStateException: stream is al bewerkt of gesloten

Na de #findAny () methode wordt aangeroepen, de stringStream is gesloten, daarom elke verdere bewerking op de Stroom zal de IllegalStateException, en dat is wat er gebeurde na een beroep op de #findFirst () methode.

3. De oplossing

Simpel gezegd, de oplossing bestaat uit het creëren van een nieuw Stroom elke keer dat we er een nodig hebben.

We kunnen dat natuurlijk handmatig doen, maar dat is waar de Leverancier functionele interface wordt echt handig:

Leverancier streamSupplier = () -> Stream.of ("A", "B", "C", "D"); Optioneel resultaat1 = streamSupplier.get (). FindAny (); System.out.println (result1.get ()); Optioneel resultaat2 = streamSupplier.get (). FindFirst (); System.out.println (result2.get ());

Als resultaat:

A A

We hebben de streamSupplier object met het type Stroom, wat precies hetzelfde type is als de #krijgen() methode retourneert. De Leverancier is gebaseerd op een lambda-expressie die geen invoer nodig heeft en een nieuw retourneert Stroom.

Een beroep doen op de functionele methode krijgen() op de Leverancier geeft een vers aangemaakt Stroom object, waarop we veilig een ander kunnen uitvoeren Stroom operatie.

5. Conclusie

In deze korte zelfstudie hebben we gezien hoe u terminalbewerkingen uitvoert op een Stroom meerdere keren, terwijl je de beroemde vermijdt IllegalStateException dat wordt geworpen wanneer de Stroom is al gesloten of geopereerd.

Je kunt de volledige broncode en alle codefragmenten voor dit artikel vinden op GitHub.