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.
Některé z výhod streamů:
Ve většině případů se potrubí proudů skládá z
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 může pocházet ze sbírek, seznamů, sad, polí int, longů, double, řetězců atd.
Streamování operací jsou buď střední nebo terminální:
Mezi zprostředkující operace patří:
Je povolen pouze jeden provoz terminálu.
Některé příklady redukčních funkcí jsou:
Podívejme se nyní na výše uvedené koncepty v příkladech kódu.
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
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
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
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
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
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.
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é.
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ů.
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
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
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