Streamy primitívneho typu v prostredí Java 8

1. Úvod

Stream API bol jednou z kľúčových funkcií pridaných do Java 8.

Stručne povedané, API nám umožňuje pohodlne a efektívnejšie spracovávať zbierky a ďalšie sekvencie prvkov poskytovaním deklaratívneho API.

2. Primitívne toky

Streamy primárne pracujú so zbierkami objektov, nie s primitívnymi typmi.

Našťastie poskytnúť spôsob práce s tromi najpoužívanejšími primitívnymi typmi - int, dlho a dvojitý - štandardná knižnica obsahuje tri primitívne špecializované implementácie: IntStream, LongStream, a DoubleStream.

Primitívne streamy sú obmedzené hlavne kvôli réžii boxu a vytváraniu špecializovaných streamov pre iné primitívy nie je v mnohých prípadoch také užitočné.

3. Aritmetické operácie

Začnime niekoľkými zaujímavými metódami pre veľmi používané aritmetické operácie, ako sú napr min, max, súčeta priemer:

int [] cele cisla = new int [] {20, 98, 12, 7, 35}; int min = Arrays.stream (celé čísla) .min () .getAsInt (); // vráti 7

Poďme si teraz prejsť fragment kódu vyššie, aby sme pochopili, o čo ide.

Vytvorili sme naše IntStream používaním java.util.Arrays.stream (int []) a potom použil min () metóda na získanie najnižšieho celého čísla ako java.util.OptionalInt a nakoniec zavolal getAsInt () získať int hodnotu.

Ďalším spôsobom, ako vytvoriť IntStream používa IntStream.of (int…). The max () metóda vráti najväčšie celé číslo:

int max = IntStream.of (20, 98, 12, 7, 35) .max () .getAsInt (); // vráti 98

Ďalej - aby sme dostali súčet celých čísel, ktoré práve nazývame suma () metóda a nemusíme používať getAsInt () pretože už vráti výsledok ako int hodnota:

int sum = IntStream.of (20, 98, 12, 7, 35). sum (); // vráti 172

Vyvolávame priemer () metóda na získanie priemeru celočíselných hodnôt a ako vidíme, mali by sme ju použiť getAsDouble () pretože vracia hodnotu typu dvojitý.

double avg = IntStream.of (20, 98, 12, 7, 35) .average () .getAsDouble (); // vráti 34.4

4. Rozsah

Môžeme tiež vytvoriť IntStream na základe rozsahu:

int sum = IntStream.range (1, 10) .sum (); // vráti 45 int sum = IntStream.rangeClosed (1, 10) .sum (); // vráti 55

Ako ukazuje útržok kódu vyššie, existujú dva spôsoby, ako vytvoriť rozsah celočíselných hodnôt rozsah () a rangeClosed ().

Rozdiel je v tom, že koniec rozsah () je exkluzívny, zatiaľ čo je zahrnutý v rangeClosed ().

Metódy rozsahu sú k dispozícii iba pre IntStream a LongStream.

Range môžeme použiť ako efektnú formu slučky for-each:

IntStream.rangeClosed (1, 5) .forEach (System.out :: println);

Čo je dobré pri ich použití ako náhrady slučky for-each je, že môžeme tiež využiť výhody paralelného vykonávania:

IntStream.rangeClosed (1, 5) .parallel () .forEach (System.out :: println);

Aj keď sú tieto efektné slučky užitočné, je stále lepšie použiť tradičné slučky for-loop namiesto funkčných na jednoduché iterácie, pretože v niektorých prípadoch sú jednoduché, čitateľné a výkonné.

5. Box a Unboxing

Sú chvíle, kedy potrebujeme previesť primitívne hodnoty na ich obalové ekvivalenty.

V týchto prípadoch môžeme použiť škatuľka () metóda:

Zoznam evenInts = IntStream.rangeClosed (1, 10) .filter (i -> i% 2 == 0) .boxed () .collect (Collectors.toList ());

Môžeme tiež konvertovať z prúdu triedy wrapper na primitívny prúd:

// vráti 78 int sum = Arrays.asList (33,45) .stream () .mapToInt (i -> i) .sum ();

Vždy môžeme použiť mapToXxx a flatMapToXxx metódy na vytváranie primitívnych prúdov.

6. Záver

Java Streams je veľmi silný doplnok k jazyku. Sotva sme tu poškriabali povrch primitívnych prúdov, ale ako už môžete použiť na svoju produktivitu.

A ako vždy, vzorky kódu nájdete na GitHub.


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