Streamy jsou jednou z klíčových funkcí programovacího jazyka Java, která poskytuje pohodlné a efektivní nástroje pro práci s datovými sbírkami. Použití streamů výrazně zjednodušuje proces zpracování a filtrování dat a také umožňuje optimalizaci kódu pomocí paralelních výpočtů.
Hlavním principem streamování je vytváření datových řetězců. Každá operace je funkční rozhraní, které se vztahuje na prvky streamu. Takové operace mohou být například filtrování podle konkrétní podmínky, třídění, převod dat a další.
Hlavní výhodou streamů v Javě je lenivost, tedy provádění operací pouze v případě potřeby. Pokud je například operace filtrování přítomna v řetězci operací, bude provedena pouze pro prvky, které splňují danou podmínku, zatímco ostatní prvky budou ignorovány.
Kromě toho streamy v Javě podporují paralelní výpočty, což umožňuje paralelní operace a efektivní využití zdrojů počítače. K tomu stačí u streamu vyvolat metodu parallel (). Je však třeba si uvědomit, že ne všechny operace podporují paralelní výpočty a použití streamů s paralelními operacemi není vždy účinné.
V tomto článku se podíváme na základní principy fungování streamů v Javě a možnosti jejich použití. Naučíme se, jak vytvářet streamy, používat datové operace, používat paralelní výpočty a řešit netriviální problémy pomocí streamů. Také se naučíme ladění a profilování streamů, abychom optimalizovali kód a zlepšili jeho výkon.
Základní pojmy streamů v Javě
Streamy představují nový koncept v Javě 8 pro práci s datovými sbírkami. Poskytují možnost provádět různé operace nad prvky sbírky, jako je filtrování, třídění, sumarizace a další, bez použití cyklů.
Základní pojmy streamů:
Zdroj dat: stream získává svá data ze zdroje, kterým může být sbírka, pole nebo jakýkoli jiný objekt, který poskytuje metoda stream(). Pro sbírku List lze například získat stream takto: list.stream().
Přechodné operace: jedná se o operace, které mohou být aplikovány na Stream po jeho vytvoření, ale před terminální operací. Meziprodukty nemění původní data, ale vytvářejí nový Stream, který obsahuje výsledky operace. Některé příklady mezilehlých operací zahrnují filter (), map () a ported ().
Terminální operace: je to operace, která vede k výpočtu a dokončení streamu. Obvykle vracejí nějakou hodnotu nebo provádějí vedlejší účinky. Příklady terminálních operací jsou forEach (), reduce () a collect ().
Zpracování dat pomocí streamů v Javě umožňuje psát kompaktnější a expresivnější kód, usnadňuje čtení a pochopení algoritmu zpracování dat. Umožňují také provádět operace paralelně, což zlepšuje výkon v multipotykových aplikacích.
Výhody používání streamů
Použití streamů v Javě nabízí několik výhod, díky nimž je Kód čitelnější, podporovanější a efektivnější:
- Snadné čtení a zápis dat: streamy vám umožňují stručně a efektivně číst a zapisovat data z různých zdrojů, jako jsou soubory, sbírky a další.
- Funkční programování: streamy nabízejí možnost použití funkčního programování v Javě. Umožňují použití výrazů lambda a funkčních rozhraní pro flexibilnější zpracování dat.
- Paralelní zpracování dat: streamy podporují paralelní zpracování dat, což umožňuje efektivní využití více vláken a rychlejší provádění úkolů.
- Skrývání složitých operací: streamy umožňují zakrýt složitost operací zpracování dat, jako je filtrování, třídění a konverze, pomocí řetězce jednoduchých metod.
- Vylepšená čitelnost kódu: použití streamů vám umožňuje napsat kód, který je pro ostatní vývojáře snadněji čitelný a srozumitelný. Stává se deklarativnějším a expresivnějším než tradiční cykly a konstrukce.
Celkově streamy v Javě poskytují výkonný nástroj pro zpracování dat, který výrazně zjednodušuje a zlepšuje proces psaní kódu. Přispívají ke zvýšení produktivity a usnadňují implementaci různých datových operací.
Jak vytvořit stream v Javě
K vytvoření streamu v Javě lze použít několik způsobů:
List numbers = Arrays.asList(1, 2, 3, 4, 5);Stream stream = numbers.stream();
int[] array = ;IntStream stream = Arrays.stream(array);
Stream stream = Stream.of("Java", "Python", "C++");
Stream randomStream = Stream.generate(Math::random);
Stream evenNumbers = Stream.iterate(0, n -> n + 2);
Výše uvedené způsoby demonstrují různé možnosti vytváření streamů v Javě. Jaký způsob použití závisí na konkrétním úkolu a dostupnosti dat. Streamy umožňují pohodlnější a flexibilnější práci s daty, provádění operací na mnoha prvcích, filtrování, transformaci a agregaci výsledků.
Hlavní operace se streamy
Streamy v Javě poskytují sadu operací pro práci s daty. Zde je několik základních operací, které lze použít se streamy:
- Přechodné operace: tyto operace se provádějí přímo na streamu a vracejí nový stream. Příklady takových operací zahrnují filter , map, ported a distinct . Umožňují filtrovat, převádět, třídit a odstraňovat duplicitní prvky streamu.
- Terminálové operace: tyto operace se provádějí na streamu a vracejí výsledek. Příklady takových operací zahrnují count , collect, forEach a reduce . Umožňují provádět různé akce se streamem, například spočítat počet položek, shromáždit položky do sbírky, provést akci pro každý prvek atd.
- Paralelní operace: streamy také podporují paralelní zpracování dat. K tomu lze použít operace parallel a parallelStream . Umožňují rozdělit zpracování prvků mezi více vláken, což může urychlit operace.
- Dopravníkové operace: operace streamu mohou tvořit dopravník, kde se výsledek jedné operace stane vstupními údaji pro další. Můžete například použít operaci filter k výběru určitých položek a poté použít operaci map k převodu zbývajících položek.
Operace streamu nám umožňují pohodlně a efektivně zpracovávat sbírky dat ve funkčním stylu. Použití streamů může výrazně snížit počet kódů a usnadnit operace kolekcí.
Terminální a meziprodukty
Streamy v Javě poskytují sadu operací, které lze použít na prvky datového toku. Tyto operace lze rozdělit do dvou kategorií: terminální a mezilehlé.
Terminálové operace dokončí stream a vrátí výsledek. Příklady terminálních operací zahrnují metody forEach, count, anyMatch, allMatch, noneMatch a reduce. Metoda forEach umožňuje aplikovat akci na každý prvek streamování, count vrací počet prvků a metody anyMatch, allMatch a noneMatch testují, zda alespoň jeden, všechny nebo žádný prvek streamu splňuje danou podmínku. Metoda reduce umožňuje redukovat všechny prvky streamu na jednu hodnotu použitím uvedené funkce s baterií.
Meziprodukty převádějí nebo filtrují prvky streamu a vracejí nový stream. Příklady mezilehlých operací zahrnují metody map, filter, distinct, ported a limit. Metoda map převádí každý prvek streamu pomocí zadané funkce, filter filtruje prvky a ponechává pouze ty, které splňují danou podmínku, a metody distinct, ported a limit odstraňují duplikáty, třídí položky nebo omezují jejich počet.
Kombinace terminálních a intermediálních operací umožňuje flexibilní zpracování datového toku a provádění různých operací nad prvky streamu. Terminální operace jsou" koncovými body " streamování a bez nich nelze stream použít a meziprodukty lze sloučit do řetězce pro sekvenční aplikaci na data.
Příklad použití streamů v Javě
Podívejme se na příklad použití streamů v Javě ke zpracování sbírky prvků typu Integer:
Máme sbírku čísel: [1, 2, 3, 4, 5]. A chceme provést následující operace této sbírky:
- Filtrovat pouze lichá čísla.
- Zvýšit každé číslo o 1.
- Najít součet všech prvků.
Zde je návod, jak to udělat pomocí streamů:
List numbers = Arrays.asList(1, 2, 3, 4, 5);int sum = numbers.stream().filter(n -> n % 2 != 0).map(n -> n + 1).reduce(0, Integer::sum);System.out.println(sum); // Выведет: 9
Začínáme vytvořením streamu ze sbírky čísel pomocí metody stream (). Poté filtrujeme hodnoty pomocí Lambda-výraz n - > n % 2 != 0, která ponechává pouze lichá čísla. Poté použijeme operaci map, která každé číslo zvýší o 1.
Nakonec jsme použili metodu reduce, která vede všechny prvky streamu ke stejné hodnotě. V tomto případě jsme použili počáteční hodnotu 0 a operaci sčítání Integer::: sum , abychom našli součet všech těchto prvků.
Výsledný součet je 9, což je výsledek provedení příkladu.