Výukový program pro proudy Java 8 s příklady kódu

V tomto příspěvku na blogu pojednáme o funkcích Java 8 Streams a poskytneme spoustu různých příkladů kódu.

Streamy Java přinášejí do Java funkční programování a jsou podporovány od verze Java 8, takže pokud máte starší verzi Java, musíte upgradovat na Java 8, abyste mohli používat Java Streams.



Proč používat Java Streams?

Některé z výhod streamů:


  • Proudy z vás udělají efektivnějšího programátora jazyka Java (uvidíte, že s velmi málo řádky kódu toho pomocí streamů dosáhnete skutečně hodně).
  • Využívají výrazy lambda, což jsou jakési jednorázové funkce.
  • ParallelStreams umožňuje velmi snadno operace s více vlákny pro velké datové sady.


Potoky potoků

Ve většině případů se potrubí proudů skládá z

  • zdroj (odkud vycházejí vaše data)
  • následuje nula nebo více zprostředkující operace
  • a jeden provoz terminálu

Streamování Java - filtrování, mapování, zmenšování


Zdroj bude streamovat proud prvků.

Tento proud prvků lze filtrovat, třídit nebo ho lze mapovat nebo použít na každý prvek jinou jinou řadu operací.

Na konci to může být buď shromážděno nebo zmenšeno nebo nějaká jiná operace terminálu, ale je provedena pouze jedna operace terminálu.

Zdroj streamu

Zdroj streamu může pocházet ze sbírek, seznamů, sad, polí int, longů, double, řetězců atd.


Streamování operací

Streamování operací jsou buď střední nebo terminální:

  • Zprostředkující operace jako je filtrování, mapování nebo třídění vrací proud, abychom mohli řetězit několik mezilehlých operací.
  • Terminálové operace obdrží stream a mohou buď vrátit neplatnost, nebo mohou vrátit výsledek bez proudu, jako je snížení, např. zmenšit položky na seznam.

Zprostředkující operace

  • Nula nebo více mezilehlých operací je povoleno.
  • Na objednávce záleží; pro velké datové sady: nejprve filtrovat poté seřaďte nebo namapujte.
  • Pro velmi velké datové sady nám ParallelStream umožňuje více vláken.

Mezi zprostředkující operace patří:

  • anyMatch ()
  • odlišný()
  • filtr()
  • findFirst ()
  • flatmap ()
  • mapa()
  • přeskočit()
  • tříděno ()

Provoz terminálu

Je povolen pouze jeden provoz terminálu.

  • forEach aplikuje stejnou funkci na každý prvek, například vytiskne každý prvek.
  • collect uloží všechny prvky do kolekce nebo seznamu nebo pole.
  • všechny ostatní možnosti redukují stream na jeden souhrnný prvek.

Některé příklady redukčních funkcí jsou:


  • počet()
  • max ()
  • min ()
  • snížit()


Příklady kódu Java Streams

Podívejme se nyní na výše uvedené koncepty v příkladech kódu.

Integer Stream

První příklad je pouze celočíselný proud. Chystáme se vytvořit celočíselný proud pomocí IntStream třída a její funkce rozsahu, která nám dává rozsah celých čísel.

The forEach je náš terminál. U každé položky si ji jen vytiskneme.

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream

.range(1, 10)

.forEach(System.out::print);
System.out.println();
} }

Výstup:


123456789

Celočíselný proud s přeskočením

Druhý příklad používá celočíselný proud, ale přidali jsme skip() zde tedy v tomto případě přeskočíme prvních 5 prvků našeho streamu.

Budou to pouze tiskové prvky 6 až 9. K tisku položky používáme také jednoduchý výraz lambda

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream

.range(1, 10)

.skip(5)

.forEach(x -> System.out.println(x));
System.out.println();
} }

Výstup:

6 7 8 9

Celočíselný proud se součtem

Třetí příklad opět použijeme IntStream abychom vytvořili náš proud objektů, vložili jsme to však do println() příkaz jako parametr tiskové linky.


To, co budeme tisknout, je pouze součet z rozsahu 1 až 5, jinými slovy, 1 2 3 a 4 se vytiskne pouze součet těchto čísel:

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
System.out.println(
IntStream

.range(1, 5)

.sum());
System.out.println();
} }

Výstup:

10

Stream.of

Následující příklad používá Stream.of funkce, která je opravdu užitečná, protože můžete streamovat celá čísla, hodnoty s plovoucí desetinnou čárkou nebo řetězce nebo dokonce objekty.

V tomto příkladu provedeme přímý abecední řazení, potom najdeme první položku pomocí findFirst() funkce. Potom už jen vytiskneme první položku v seznamu.

import java.io.IOException; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream.of('Ava', 'Aneri', 'Alberto')

.sorted()

.findFirst()

.ifPresent(System.out::println);
} }

Výstup

Alberto

Streamujte z pole, tříděte, filtrujte a tiskněte

V našem dalším příkladu budeme streamovat z pole. Pak budeme třídit, filtrovat a poté tisknout.

Zde odfiltrujeme pouze položky, které začínají s.

Používáme výraz lambda, který přebírá X což je každé jméno a poté zkontroluje, které začínají písmenem s a předá to dál.

Potom je roztřídíme a potom pro každou položku, která danému řazení projde, ji vytiskneme.

import java.io.IOException; import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) throws IOException {
String[] names = {'Al', 'Ankit', 'Kushal', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah'};
Arrays.stream(names)


.filter(x -> x.startsWith('S'))


.sorted()


.forEach(System.out::println);
} }

Výstup:

Sarah Sarika Shivika

Průměr celočíselného pole

Nyní se podívejme na to, jak můžeme vzít průměr čtverců int pole.

Zde používáme Arrays.stream() funkce pro streamování celých čísel a potom použijeme map() mapovat každou položku každé celé číslo na její čtverec.

import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) {
Arrays.stream(new int[] {2, 4, 6, 8, 10})


.map(x -> x * x)


.average()


.ifPresent(System.out::println);
} }

Výstup:

44.0

Všimněte si, že se vytiskne dvakrát místo celého čísla.

Streamujte ze seznamu, filtrujte a tiskněte

V tomto příkladu budeme streamovat ze seznamu, filtrovat tyto položky a poté tisknout.

Všimněte si, že v rámci map() funkce převedeme všechna jména na malá písmena.

import java.util.Arrays; import java.util.List; public class JavaStreams {
public static void main(String[] args) {
List people = Arrays.asList('Al', 'Ankit', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah');
people


.stream()


.map(String::toLowerCase)


.filter(x -> x.startsWith('a'))


.forEach(System.out::println);
} }

Výstup:

al ankit amanda

Vidíme, že máme tři jména, která začínají a a všechny jsou malé.

Streamujte řádky z textového souboru, tříděte, filtrujte a tiskněte

V našem dalším příkladu budeme streamovat řádky z textového souboru. Budeme třídit, filtrovat a tisknout.

Předpokládejme, že máme soubor s názvem bands.txt s obsahem uvedeným níže:

Rolling Stones Lady Gaga Jackson Browne Maroon 5 Arijit Singh Elton John John Mayer CCR Eagles Pink Aerosmith Adele Taylor Swift

Budeme používat Files.lines() abychom vytvořili náš stream, který nám dá proud řetězce pro každý řádek souboru.

Jakmile budeme mít svůj stream, budeme je třídit a budeme filtrovat položky, které mají více než 13 znaků, a poté vytisknout zbývající položky.

Nakonec musíme soubor zavřít, abychom udělali bands.close.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream bands = Files.lines(Paths.get('bands.txt'));
bands


.sorted()


.filter(x -> x.length() > 13)


.forEach(System.out::println);
bands.close();
} }

Výstup:

Jackson Browne Rolling Stones

Dostaneme dvě kapely, které mají více než 13 znaků.

Streamujte řádky z textového souboru a ukládejte do seznamu

V tomto příkladu použijeme stejný textový soubor jako výše.

Chceme odfiltrovat položky obsahující písmena jit pomocí x.contains() což je pouze řetězcová funkce.

Pomocí .collect() přidáme všechny s písmeny jit do seznamu.

Jakmile máme seznam, můžeme použít forEach operátor pro tisk položek.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; public class JavaStreams {
public static void main(String[] args) throws IOException {
List bands2 = Files.lines(Paths.get('bands.txt'))


.filter(x -> x.contains('jit'))


.collect(Collectors.toList());
bands2.forEach(x -> System.out.println(x));
} }

Výstup:

Arijit Singh

Streamujte řádky ze souboru CSV a počítejte

V tomto příkladu streamujeme řádky ze souboru CSV a budeme počítat dobré řádky.

Předpokládejme, že máme soubor s názvem data.txt s následujícím obsahem:

A,12,3.7 B,17,2.8 C,14,1.9 D,23,2.7 E F,18,3.4

Řádek E zde nemá žádná data, takže ho chceme z našeho streamu vyloučit.

V následujícím kódu budeme číst v každém řádku a poté je nutné rozdělit čárkami do pole, aby se každý řádek stal polem položek.

Poté použijeme filtr k odfiltrování řádků, které neobsahují tři položky.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream rows1 = Files.lines(Paths.get('data.txt'));
int rowCount = (int)rows1


.map(x -> x.split(','))


.filter(x -> x.length == 3)


.count();
System.out.println(rowCount + ' rows.');
rows1.close();
} }

Výstup:

5 rows

Snížení - součet

Tento příklad ukazuje, jak použít redukci. Chystáme se snížit na částku. Zde máme dvojitý proud pomocí Stream.of() funkce. Definovali jsme tři zdvojnásobení ve třech různých argumentech a použijeme funkci redukce.

import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) {
double total = Stream.of(7.3, 1.5, 4.8)


.reduce(0.0, (Double a, Double b) -> a + b);
System.out.println('Total = ' + total);
} }

Výstup:

13.600000000000001