„Stream už bol prevádzkovaný alebo uzavretý“ Výnimka v Jave

1. Prehľad

V tomto krátkom článku si povieme niečo spoločné Výnimka s ktorými sa môžeme stretnúť pri práci s Prúd trieda v Jave 8:

IllegalStateException: stream už bol prevádzkovaný alebo uzavretý.

Objavíme scenáre, kedy dôjde k tejto výnimke, a možné spôsoby, ako sa jej vyhnúť, spolu s praktickými príkladmi.

2. Príčina

V prostredí Java 8 každý Prúd trieda predstavuje jednorazovú postupnosť údajov a podporuje niekoľko I / O operácií.

A Prúd by sa mali zapnúť (vyvolanie operácie stredného alebo koncového toku) iba raz. Streamová implementácia môže hádzať IllegalStateException ak zistí, že Prúd sa opätovne používa.

Kedykoľvek je terminálna operácia vyvolaná na a Prúd objekt sa inštancia spotrebuje a uzavrie.

Preto smieme vykonať iba jednu operáciu, ktorá spotrebuje a Prúd, inak dostaneme výnimku, ktorá uvádza, že Prúd už bol prevádzkovaný alebo uzavretý.

Pozrime sa, ako to možno preložiť do praktického príkladu:

Stream stringStream = Stream.of ("A", "B", "C", "D"); Voliteľný výsledok1 = stringStream.findAny (); System.out.println (result1.get ()); Voliteľný výsledok2 = stringStream.findFirst ();

Ako výsledok:

Výnimka vo vlákne „main“ java.lang.IllegalStateException: prúd už bol spustený alebo zatvorený

Po #findAny () metóda je vyvolaná, stringStream je uzavretá, preto je akákoľvek ďalšia operácia na Prúd bude hádzať IllegalStateException, a to sa stalo po vyvolaní súboru #findFirst () metóda.

3. Riešenie

Jednoducho povedané, riešenie spočíva vo vytvorení nového Prúd zakaždým, keď jeden potrebujeme.

Môžeme to, samozrejme, robiť manuálne, ale tam je to Dodávateľ funkčné rozhranie sa stáva skutočne praktickým:

Dodávateľ streamSupplier = () -> Stream.of ("A", "B", "C", "D"); Voliteľný výsledok1 = streamSupplier.get (). FindAny (); System.out.println (result1.get ()); Voliteľný výsledok2 = streamSupplier.get (). FindFirst (); System.out.println (result2.get ());

Ako výsledok:

A A

Definovali sme streamDodávateľ objekt s typom Prúd, čo je presne ten istý typ, aký #get () metóda sa vracia. The Dodávateľ je založené na výraze lambda, ktorý neberie žiadny vstup a vráti nový Prúd.

Vyvolanie funkčnej metódy dostať () na Dodávateľ vracia čerstvo vytvorené Prúd objekt, na ktorom môžeme bezpečne vykonať ďalší Prúd prevádzka.

5. Záver

V tomto rýchlom výučbe sme videli, ako vykonávať operácie terminálu na a Prúd viackrát, pričom sa vyhýbate slávnym IllegalStateException ktorý sa hodí, keď Prúd je už zatvorená alebo prevádzkovaná.

Kompletný zdrojový kód a všetky útržky kódu pre tento článok nájdete na GitHub.