1. Elemek gyűjtése

Végül elérkeztünk az Streamosztály legérdekesebb módszeréhez, a collect()metódushoz. Arra használják, hogy az adatfolyamokról átkerüljenek ismerős gyűjteményeinkbe – List<T>, Set<T>, Map<T, R>és mások.

A collect()metódus egy speciális collectorobjektumot vesz fel argumentumként. Ez az objektum beolvassa az összes adatot az adatfolyamból, átalakítja egy meghatározott típusú gyűjteménybe, és visszaadja. És akkor maga a gyűjtési metódus adja vissza ezt a gyűjteményt.

Mindez meglehetősen sima módon történik: az collectorobjektum típusa Collector<T, A, R>. Mint látható, három típusparamétere van. Az utolsó típusparaméter ( R) általában olyan típusú, mint a List<T>. Ez azt jelenti, hogy a fordító ezt a típust használhatja collect()magának a metódusnak a helyes visszatérési típusának meghatározására.

Remélem nem vagy összezavarodva. Mindenesetre nem kell saját kezűleg létrehoznia Collector objektumokat. Az osztály statikus metódusai által visszaadott kész objektumok Collectorselegendőek lesznek.

Gyűjtők osztály

Az Collectorsosztálynak számos statikus metódusa van, amelyek kész gyűjtőobjektumokat adnak vissza – minden alkalomra valamit. Itt megfontoljuk a legfontosabbakat.

toList()
Objektum, amely egy adatfolyamot listává alakít ( List<T>)
toSet()
Egy objektum, amely egy adatfolyamot halmazzá alakít ( Set<T>)
toMap()
Egy objektum, amely egy adatfolyamot térképpé alakít ( Map<K, V>)
joining()
Egy adatfolyam elemeit egyetlen karakterláncba fűzi össze
mapping()
Egy karakterlánc elemeit a-ra konvertáljaMap<K, V>
groupingBy()
Csoportosítja az elemeket és visszaadjaMap<K, V>

2. Adatfolyam átalakítása listává

Az alábbiakban egy tipikus példa egy adatfolyammal való munkavégzésre és az eredmény listává alakítására

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

List<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toList() );

Kaptunk egy folyamot a gyűjteményből. Aztán kaptunk egy új adatfolyamot úgy, hogy csak azokat a karakterláncokat tartottuk meg, amelyek első karaktere nagybetű. Ezután az adott adatfolyam összes adatát egy gyűjteménybe gyűjtik, amelyet azután visszaküldenek.



3. Stream átalakítása halmazzá

A következő egy tipikus példa egy adatfolyammal való munkavégzésre és az eredmény halmazzá konvertálására

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Hello", "how's", "life?");

Set<String> result = list.stream()
   .filter( s -> Character.isUpperCase(s.charAt(0)) )
   .collect( Collectors.toSet() );

Minden nagyon hasonlít a folyamok konvertálására szolgáló kódhoz List, csak egy másik gyűjtőobjektumot használunk, amelyet a toSet()metódus ad vissza.



4. A patak átalakítása térképpé

De egy adatfolyamot térképpé konvertálni egy kicsit nehezebb. A térkép minden bejegyzése két elemből áll: egy kulcsból és egy értékből. Ki kell találnunk, hogyan fogjuk meghatározni a kulcsot és az értéket az adatfolyam egyes elemeihez.

Példa:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");

Map<String, String> result = list.stream()
   .map( e -> e.split("=") )
   .filter( e -> e.length == 2 )
   .collect( Collectors.toMap(e -> e[0], e -> e[1]) );

Nézzük meg, mi folyik itt.

Az első sorban map(...)minden karakterláncot karakterláncok tömbjévé alakítunk át. A split módszerrel minden karakterláncot két részre osztunk.

A második sorban csak azokat a tömböket adjuk át a filter()metódusnak, amelyek pontosan két elemet tartalmaznak. A d==3karakterlánc három elemből álló tömbre oszlik, ami nem egyezik a szűrővel.

És végül az utolsó sorban átalakítjuk a folyamot egy Map<String, String>. Két függvényt adunk át a toMap()metódusnak. Az adatfolyam minden eleménél az első függvénynek a kulcsot , a másodiknak pedig az értéket kell visszaadnia .

Minden tömb első eleme ("a", "b", "c") lesz a kulcsunk, és az egyes tömbök második eleme ("2", "3", "4") lesz az értékünk.



5. Adatfolyam átalakítása karakterláncsá

Egy másik érdekes gyűjtői tárgyat küld vissza Collectors.joining(). StringA folyam minden elemét egyetlen karakterláncba konvertálja és összefűzi. Példa

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "a=2", "b=3", "c=4", "d==3");
String result = list.stream().collect( Collectors.joining(", ") );