Folyamok
API adatszerkezetek feldolgozásához. Bár elsőre úgy tűnhet a listákhoz nagyon hasonlóak, a folyamok azonban nem tárolnak elemeiket, hanem "generálják" azokat.
Folyamot számos módon tudunk létrehozni:
Stream.of(1, 1, 2, 1, 3, 1, 2).forEach(n -> System.out.println(n));
Streamek végtelen elemet is tartalmazhatnak, ezek lustán jönnek létre azaz mindig csak egy van a memóriában.
Stream.iterate(1, n -> n + 1).forEach(n -> System.out.println(n));
// le is lehet limitálni
Stream.iterate(1, n -> n + 1).limit(10).forEach(n -> System.out.println(n));
A folyamok életciklusát három fázisra tudjuk osztani:
- létrehozás
- köztes műveletek (intermediate operation)
- lezáró művelet (termination)
Egy adott folyamot csak egyszer lehet feldolgozni, a lezáró művelet meghívását követően további műveletek meghívása IllegalStateException
-t eredményez!
Hasonlóan a lambdákhoz, vannak a primitív típusokra specializált folyamok (például: IntStream
).
Az IntStream
használata nem csak hatékonyság miatt ajánlott, hanem extra létrehozó műveletekkel rendelkezik.
IntStream.range(0, 10); // balról zárt jobbról nyitott
IntStream.rangeClosed(0, 10); // zárt
Létrehozó műveletek
Iterate
Egy kezdeti értéket és egy UnaryOperator
lambdát vár.
Stream.iterate(0, n -> n + 1).limit(5).forEach(System.out::println); // 0 1 2 3 4
Generate
Egy Supplier
lambda alapján állítja elő a folyamot:
Stream.generate(() -> 5).limit(3).forEach(System.out::println); // 5 5 5
Collection.stream()
Az egyik leggyakrabban használt létrehozó művelet a Collection
interfész stream()
metódusa, mely egy adott
gyűjtemény "folyamkénti" feldolgozását teszi lehetővé. A folyam változtatása nem változtatja meg az adatszerkezetet.
ArrayList<String> arrayList = new ArrayList<>();
arrayList.stream().forEach(System.out::println);
Bonyolultabb példa Map
-ekkel:
Map.of('a', 1, 'b', 2).entrySet().stream().forEach(entry -> System.out.println(entry.getKey())); // a b
entrySet()
aMap
bejegyzéseinek halmazavalues()
aMap
értékeinek gyűjteményekeySet()
aMap
kulcsainak halmaza
Érdekesség, hogy a következőt is meg tudjuk tenni:
Map.of('a', 1, 'b', 2).entrySet().forEach(entry -> System.out.println(entry.getKey()));
Ekkor azonban nem folyamot, hanem az Iterable
interfész adta forEach
metódust használjuk, a stream API további lehetőségeket nem tudnánk használni.