poznáme.it Programovanie Java 8: Streamy

Java 8: Streamy

Ak by ste sa pýtali, aké sú najväčšie novinky v Jave 8, tak odpoveď bude jednoznačne, že Lambda výrazy (referencie na metódy) a Streamy. O tom prvom som už písal tu. O tom druhom si povieme teraz. Streamy sú nový spôsob ako pracovať s množinami údajov. A podobne ako Lambda výrazy, aj oni tak trochu posúvajú Javu do sveta funkcionálnych jazykov.

Streamy predstavujú nový prístup k spracovaniu údajov. Na prvý pohľad by sa mohlo zdať, že je to len ďalšia forma kolekcií, ale ich implementácia je zásadne iná a vďaka tomu majú niekoľko výrazne iných vlastností. Streamy sa dajú charakterizovať troma vlastnosťami:

  • deklaratívnosť – práca s nimi pripomína viac deklaratívne jazyky (napr. SQL), kde hovoríte kódom, čo chcete dostať a nie ako to dosiahnuť
  • komponovateľnosť – spracovanie streamu (ako si o chvíľu ukážeme) je séria operácií, ktoré sa dajú jednoducho radiť jedna k druhej
  • paralelizmus – od sekvenčného spracovania streamu k paralelnému sa dá dostať veľmi jednoducho. Streamy sú budované tak, aby paralelizmus bol úplne transparentný.

Aby tej teórie nebolo príliš, poďme si ukázať jednoduchý príklad. Máme zoznam mien, z ktorého chceme získať dĺžky jednotlivých položiek a pre tie, čo majú viac ako 5 znakov, vypísať ich dĺžku:

List<String> names = new ArrayList<>();
names.add("Lubomir");
names.add("Ivana");
names.add("Jan");
names.add("Ludmila");
List<Integer> filterNames = names.stream()
.map(String::length)
.filter(nameLength -> nameLength > 5)
.collect(Collectors.toList());
filterNames.forEach(value -> System.out.println(value));

Prvých päť riadkov je klasika. Len definujeme pole a napĺňame ho údajmi. Zaujímavé to začne byť až volaním names.stream(). To je moment, kedy sa zo sveta klasických kolekcií dostávame do sveta streamov. Výsledkom tohto volania je stream, ktorý následne necháme spracovať sériou operácií. Najprv reťazce prekonvertujeme na ich dĺžky a následne necháme cez filter prejsť len tie, ktoré majú viac ako 5 znakov. Na záver z položiek, ktoré ostali v streame, zostavíme nový zoznam. Ten potom vypíšeme do konzoly.

Toto je krátka ukážka toho, ako sa dá so streamami pracovať. Poďme ale pekne po poriadku. Ako vieme stream vytvoriť?

  • zo zoznamu hodnôt: Stream.of(„Jan“, „Frantisek“, „Martin“);
  • z poľa: Arrays.Stream(pole);
  • zo súboru: Files.lines(cesta_k_suboru);
  • generovaním: Stream.generate(Math::random);
  • iteratívnym volaním metódy: Stream.iterate(0, n -> n+2);

Stream máme vytvorený, čo sa s ním dá robiť? Operácie, ktoré stream podporuje, sa delia do dvoch kategórií:

  1. prechodné (alebo tranzitné) – vracajú opäť objekt stream, takže je k ním možné pripojiť ďalšie operácie streamu
  2. konečné – vracajú iný objekt ako stream, takže ukončujú spracovanie streamu

V našom príklade boli metódy map a filter prechodné metódy a metóda collect konečná. Takto vyzerá zoznam prechodných funkcií:

  • filter – v streame ďalej pokračujú len objekty, ktoré splnia predikát
  • distinct – v streme budú už len jedinečné hodnoty
  • limit(n) – v streame ostane len prvých n prvkov
  • skip(n) – prvých n prvkov je zo streamu vylúčených
  • map – vykoná nejakú operáciu nad každým prvkom. Výsledok tej operácie môže byť aj prvok iného typu.
  • flatMap – to isté ako predchádzajúci prípad, ale ak je výsledok operácie pole, tak nedostanem stream polí, ale stream prvkov (namiesto streamu polí len stream prvok všetkých polí)
  • sorted – usporiadanie streamu (stream štandardne zachováva poradie od vytvorenia až po koniec spracovania)

A takto vyzerá zoznam konečných metód:

  • forEach – vykoná operácie nad každým prvkom (návratovou hodnotou je void)
  • collect – zo streamu vytvorí kolekciu podľa zadaného kolektora
  • allMatch – vráti true, ak všetky prvky v streame spĺňajú podmienku
  • noneMatch – vráti true, ak ani jeden prvok v streame nespĺňa podmienku
  • anyMatch – vráti true, ak aspoň jeden prvok v streame spĺňa podmienku
  • findAny – vráti náhodný prvok zo streamu vo forme Optional objektu
  • findFirst – vráti prvý prvok zo streamu vo forme Optional objektu
  • count – vráti počet prvok v streame
  • reduce – zredukuje stream na jednu hodnotu podľa zadanej operácie

Variabilita práce so streamami je naozaj veľká. Stačí kombinovať rôzne prechodné funkcie a ukončiť správnou konečnou funkciou. Napr. konečná metóda reduce je celkom zaujímavá, pretože zredukuje pole do jednej hodnoty podľa nejakej operácie. Stačí jej teda dodať operáciu, ktoré z dvoch hodnôt robí jednu a ona vám zo streamu vyrobí nakoniec len jednu hodnotu (spolu s operáciou map tvoria známe duo z map-reduce algoritmu). Napr. podľa operácií Math.max alebo Math.min:

Optional<Integer> minValue = list.stream().reduce(Math::max);
Optional<Integer> maxValue = list.stream().reduce(Math::min);

Toto všetko je len úvod do oblasti streamov. Nespomenul som, že existujú aj typové streamy: IntStreamDoubleStream a LongStream. Tieto nie len šetria energiu a čas tým, že nerobia boxing a unboxing nad prvkami, ale poskytujú tiež operácie relevantné daným typom. Nespomenul som tiež, že sa dá implementovať vlastný Collector (trieda, ktorú potrebuje collect metóda), alebo že sa prvky v streame dajú zoskupovať na základe definovanej operácie. A tiež som nespomenul, že medzi obyčajným streamom a paralélnym je len takýto malý rozdiel vo vytvorení:

Optional<Integer> max = list.parallelStream().reduce(Math::max);

Nevolám teda metódu stream ale parallelStream. Výsledok je, že operácie sa môžu v streame vykonávať paralelne. Ale to, či sa to nakoniec udeje, je závislé od toho, aké operácie sa so stream budú vykonávať.

Téma streamov je naozaj široká a pokojne by zaplnila niekoľko takýchto článkov. Účelom tohto bolo ukázať, že je to téma nanajvýš zaujímavá. Zásadné je uvedomiť si, že stream nie je nový druh kolekcie. Je objekt s úplne novou filozofiou, vnútornou implementáciou, a teda aj možnosťami. Je to každopádne nástroj, ktorý má určite svoje scenáre použitia, v ktorých je lepší ako čokoľvek iné.

Text je s dovolením autora prebratí z Blogu Petra Špirenga.


Dobrý článok? Chceš dostávať ďalšie?

Už viac ako 6 200 ITečkárov dostáva správy e-mailom. Nemusíš sa báť, nie každé ráno. Len občasne.



Súhlasím so spracovaním mojich osobných údajov. ( Viac informácií. )

Tvoj email neposkytneme 3tím stranám. Posielame naňho len informácie z robime.it. Kedykoľvek sa môžeš odhlásiť.

Redakcia Robime.it
robime.ithttps://robime.it
Som admin portálu robime.it. Mám rád svoju prácu. Som tu preto, aby som Vám pomohol zodpovedať Vaše otázky k robime.it.

Android Developer

Máš rád svoju slobodu, pracuješ na projektoch, ideálne remote? Máme pre teba projekt na kontrakt s odmenou 3500 - 4000+...

iOS Developer

Máš rád svoju slobodu, pracuješ na projektoch, ideálne remote? Máme pre teba projekt na kontrakt s odmenou 3500 - 4000+...

JavaScript Developer

Slovenská firma, ktorá má ambície vybodovať svetovú UX research platformu rozširuje svoj tím a hľadá JavaScript Developera. Pracoval by si...

Linux Admin

Pre spoločnosť, ktorá sa sa zaoberá hostingom webov a aktuálne rýchlo expanduje, hľadáme Linux Admina. Môžeš pracovať na kontrakt alebo...

Lead Developer Architect

Hľadáš istotu a stabilitu v zamestnaní? Medzinárodná spoločnosť, ktorá vyvíja finančný softvér hľadá Lead Developer Architect-a. Ide o prácu na...

.NET Developer

Máš rád svoju slobodu, pracuješ na projektoch, ideálne remote? Máme príležitosť pre .NET Developera. Projekt je na kontrakt s odmenou...

Tester_remote

Pracuj na svetovom SW produkte, ktorý je používaný miliónmi používateľov! Firma rýchlo rastie a vyvíja nové features. Poznáme ich prostredie...

GIRL´S DAY už po ôsmy raz priblíži stredoškoláčkam svet technológií

Už po ôsmy raz sa uskutoční celoslovenské podujatie GIRL´S DAY, ktoré prepája IT firmy a organizácie so stredoškoláčkami po...

Čo chcú ITčkári od firiem: Peniaze, peniaze, peniaze

V predchádzajúcich častiach ankety "Čo chcú ITčkári" sme sa pozreli na dopady pandémie na prácu v IT a ako...

Firmy častokrát nevedia využívať svoje dáta ako relevantný podklad pre rozhodovanie

Kvalitná analýza dát sa stáva v čoraz nevyspytateľnejšom ekonomickom prostredí jedným z najdôležitejších podkladov pre riadenie firiem. Konferencia Power BI Day...

Čítaj ďalej:

Dobrý článok? Chceš dostávať ďalšie?

Už viac ako 6 200 ITečkárov dostáva správy e-mailom. Nemusíš sa báť, nie každé ráno. Len občasne.

Súhlasím so spracovaním mojich osobných údajov. ( Viac informácií. )

Tvoj email neposkytneme 3tím stranám. Posielame naňho len informácie z robime.it. Kedykoľvek sa môžeš odhlásiť.