Legutóbb a
Java 8 funkcionális interfészeivel ismerkedtünk meg, most pedig következzen a Stream API. A Java 8 könyvtárakhoz kapcsolódó legnagyobb változások a Collections API-t érintették, többek között megalkották a Stream API-t, amivel a Collection-ben lévő objektumokat - kihasználva a
Lambda kifejezések lehetőségeit - most már stream-ként is feldolgozhatunk.
A Stream API előtti időkben ha egy listát akartunk bejárni, akkor külső
(external) iterációt alkalmaztunk, ami feleslegesen terjengőssé tette a kódot valamint a párhuzamosított végrehajtásra való átállás esetén az egészet újra kellett írnunk. A
Stream API egy olyan fluent megoldást ad a kezünkbe, ahol nem kell külön for ciklusokat definiálnunk, az iteráció (
internal) részleteit lekezeli az API.
List<String> fruitList =
Arrays.asList("Alma","BaNÁN","KÖRTE","szILVA","BaracKok","kiwi");
// external iteration
long xcount = 0;
for (String str : fruitList) {
if (str.length() == 4)
xcount++;
}
System.out.println(xcount); //2
// internal iteration with Stream API
xcount=fruitList.stream().filter(str -> str.length() == 4).count()
System.out.println(xcount); //2
Az fenti kódrészlet megszámolja a 4 karakteres String-eket a Java 8 előtti és a Stream API által bevezetett iteráció használatával. Az
internal iterációnál maradva, a stream() hívással elkérjük a listában található objektumok stream-jét, majd a Lambda kifejezést használó
intermediate filter() művelettel kiválogatjuk a 4 karaktereseket, végül a count()
terminate hívással lekérdezzük ezen elemek darabszámát. Érdemes tudni, hogy az
intermediate műveletek csupán konfigurációs (lazy) feladatot látnak el, a tényleges bejárás a
terminate (eager) művelet során történik meg.
Set<String> set = fruitList.stream()
.filter(str -> str.length() != 4)
.map(str -> str.toUpperCase()).collect(Collectors.toSet());
System.out.println(set); // [BARACKOK, KÖRTE, BANÁN, SZILVA]
A következő példa a nem 4 karakteres Stringeket nagybetűssé alakítja, majd az eredményt egy Set-be teszi. A map() konfigurációs művelet az értékeket egy másik értékre konvertálja át, az esetünkben minden egyes String-et - ami a filter()-ben definiált feltételnek megfelel - nagybetűssé alakít. A collect() hívással megkezdődik a Stream feldolgozása és a megfelelő objektumok bekerülnek az új Set-be.
A
folytatásban további példákat fogok mutatni a Stream API használatára. De most legyen egy kis házi feladat: a filter() és a map() milyen funkcionális interfészt használ paraméterként?