Mali by sme uzavrieť stream Java?

1. Prehľad

Po zavedení výrazov lambda v prostredí Java 8 je možné písať kód stručnejším a funkčnejším spôsobom. Prúdy a funkčné rozhrania sú jadrom tejto revolučnej zmeny na platforme Java.

V tomto rýchlom výučbe sa dozvieme, či by sme mali explicitne uzavrieť prúdy Java 8 tým, že sa na ne pozrieme z pohľadu zdrojov.

2. Uzatváranie prúdov

Streamy Java 8 implementujú Automatické uzatváranie rozhranie:

verejné rozhranie Stream rozširuje BaseStream {// vynechané} verejné rozhranie BaseStream rozširuje automatické uzatváranie {// vynechané}

Zjednodušene povedané, mali by sme myslieť na prúdy ako na zdroje, ktoré si môžeme požičať a vrátiť, keď s nimi skončíme. Na rozdiel od väčšiny zdrojov nemusíme vždy uzatvárať streamy.

Spočiatku to môže znieť protiintuitívne, takže sa pozrime, kedy by sme mali a kedy nemali uzatvárať streamy Java 8.

2.1. Kolekcie, polia a generátory

Väčšinou tvoríme Prúd inštancie zo zbierok Java, polí alebo funkcií generátora. Napríklad tu pracujeme na zbierke String prostredníctvom Stream API:

Zoznam farieb = List.of ("Červená", "Modrá", "Zelená") .stream () .filter (c -> c.length ()> 4) .map (String :: toUpperCase) .collect (Zberatelia. listovať());

Niekedy generujeme konečný alebo nekonečný sekvenčný prúd:

Random random = nový Random (); random.ints (). takeWhile (i -> i <1000) .forEach (System.out :: println);

Ďalej môžeme tiež použiť prúdy založené na poli:

Farba reťazca [] = {"Červená", "Modrá", "Zelená"}; Arrays.stream (farby). Mapa (String :: toUpperCase) .toArray ()

Pri narábaní s týmito druhmi prúdov by sme ich nemali výslovne uzatvárať. Jediným hodnotným zdrojom spojeným s týmito prúdmi je pamäť a o ňu sa automaticky stará Garbage Collection (GC).

2.2. Zdroje IO

Niektoré streamy sú však zálohované prostriedkami IO, ako sú súbory alebo sokety. Napríklad Files.lines () metóda streamuje všetky riadky pre daný súbor:

Files.lines (Paths.get ("/ path / to / file")) .flatMap (line -> Arrays.stream (line.split (","))) // vynechané

Pod kapotou táto metóda otvára a FileChannel inštancia a potom ju zatvorí po uzavretí streamu. Preto Ak zabudneme stream zavrieť, zostane otvorený základný kanál a potom by sme skončili s únikom zdrojov.

Aby sa zabránilo takýmto únikom zdrojov, dôrazne sa odporúča používať vyskúšajte zdroje idiom na zatvorenie streamov založených na IO:

try (Stream lines = Files.lines (Paths.get ("/ path / to / file"))) {lines.flatMap (line -> Arrays.stream (line.split (","))) // vynechané}

Týmto spôsobom kompilátor automaticky uzavrie kanál. Kľúčovým riešením je zavrieť všetky prúdy založené na vstupoch a výstupoch.

Upozorňujeme, že zatvorenie už uzavretého streamu by vyvolalo chybu IllegalStateException.

3. Záver

V tomto krátkom tutoriáli sme videli rozdiely medzi jednoduchými streammi a IO-heavy. Dozvedeli sme sa tiež, ako tieto rozdiely informujú naše rozhodnutie o tom, či uzavrieť alebo nezavrieť prúdy Java 8.

Ako obvykle je vzorový kód k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found