Trebamo li zatvoriti Java Stream?

1. Pregled

Uvođenjem lambda izraza u Javi 8 moguće je pisati kôd na sažetiji i funkcionalniji način. Streamovi i funkcionalna sučelja srce su ove revolucionarne promjene na Java platformi.

U ovom brzom vodiču naučit ćemo trebamo li eksplicitno zatvoriti Java 8 strujanje gledajući ih iz perspektive resursa.

2. Zatvaranje tokova

Java 8 tokovi implementiraju AutoCloseable sučelje:

javno sučelje Stream proširuje BaseStream {// izostavljeno} javno sučelje BaseStream proširuje AutoCloseable {// izostavljeno}

Jednostavno rečeno, o tokovima bismo trebali razmišljati kao o resursima koje možemo posuditi i vratiti kad završimo s njima. Za razliku od većine resursa, ne moramo uvijek zatvoriti struje.

U početku ovo može zvučati kontraintuitivno, pa da vidimo kada bismo trebali i kada ne bismo trebali zatvoriti Java 8 stream.

2.1. Zbirke, nizovi i generatori

Većinu vremena stvaramo Stream primjerci iz Java kolekcija, nizova ili funkcija generatora. Na primjer, ovdje radimo na kolekciji Niz putem Stream API-ja:

Boje popisa = List.of ("Red", "Blue", "Green") .stream () .filter (c -> c.length ()> 4) .map (String :: toUpperCase) .collect (Collectors. izlistati());

Ponekad generiramo konačan ili beskonačan sekvencijalni tok:

Slučajni slučajni = novi Random (); random.ints (). takeWhile (i -> i <1000) .forEach (System.out :: println);

Osim toga, možemo koristiti i tokove temeljene na nizu:

Niz [] boje = {"Crvena", "Plava", "Zelena"}; Nizovi.stream (boje) .map (String :: toUpperCase) .toArray ()

Kad se bavimo ovakvim vrstama potoka, ne bismo ih trebali eksplicitno zatvoriti. Jedini vrijedan resurs povezan s tim streamovima je memorija, a Garbage Collection (GC) automatski se za to brine.

2.2. IO resursi

Međutim, neki tokovi podržani su IO resursima kao što su datoteke ili utičnice. Na primjer, Files.lines () metoda struji sve retke za datu datoteku:

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

Ispod haube, ova metoda otvara a FileChannel instancu, a zatim je zatvara nakon zatvaranja toka. Stoga, ako zaboravimo zatvoriti tok, temeljni kanal ostat će otvoren i tada bismo završili s curenjem resursa.

Da biste spriječili takvo curenje resursa, toplo se preporučuje korištenje pokušajte s resursima idiom za zatvaranje tokova temeljenih na IO:

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

Na taj će način prevoditelj automatski zatvoriti kanal. Ključno je rješenje za zatvaranje svih tokova temeljenih na IO-u.

Imajte na umu da bi zatvaranje već zatvorenog toka moglo baciti IllegalStateException.

3. Zaključak

U ovom kratkom vodiču vidjeli smo razlike između jednostavnih tokova i IO-teških. Također smo naučili kako te razlike informiraju našu odluku o tome hoćemo li zatvoriti Java 8 stream ili ne.

Kao i obično, uzorak koda dostupan je na GitHubu.


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