1. Kolekcja elementów

I wreszcie doszliśmy do najciekawszej metody w klasie Stream- metody collect(). Służy do przechodzenia ze strumieni do znanych kolekcji — List<T>, Set<T>, Map<T, R>i innych.

Musisz przekazać specjalny obiekt do metody collect()- collector. Ten obiekt odczytuje wszystkie dane ze strumienia, konwertuje je na określoną kolekcję i zwraca. A potem sama metoda collect zwraca tę samą kolekcję.

Wszystko to odbywa się dość sprytnie: obiekt collectorma typ Collector<T, A, R>- ma już trzy parametry typu. Ostatnim typem Rjest zwykle typ taki jak List<T>. Dlatego kompilator może zastąpić ten typ poprawnym typem wyniku samej metody collect().

Mam nadzieję, że nie jesteś zbyt zdezorientowany. W każdym razie nie musisz samodzielnie tworzyć obiektów Collector. Wystarczy skorzystać z gotowych obiektów, które zwracają statyczne metody Collectors.

Klasa kolekcjonerska

Klasa Collectorsposiada kilka metod statycznych, które zwracają gotowe obiekty kolekcjonerskie na każdą okazję. Jest ich kilkadziesiąt, ale rozważymy te najbardziej podstawowe:

toList()
Obiekt, który konwertuje strumień na listę −List<T>
toSet()
Obiekt, który konwertuje strumień na zbiór −Set<T>
toMap()
Obiekt, który konwertuje strumień na mapę −Map<K, V>
joining()
Łączy elementy strumienia w jedną linię
mapping()
Konwertuje elementy strumienia naMap<K, V>
groupingBy()
Grupy elementów, zwrotyMap <K, V>

2. Konwertuj strumień na listę

Tak wygląda typowa praca ze strumieniem i zamiana wyniku pracy na listę

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Cześć", "Jak", "дела?");

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

Otrzymaliśmy strumień z kolekcji, a następnie otrzymaliśmy z niego nowy strumień, odfiltrowując tylko wiersze, których pierwszy znak jest pisany wielką literą. Następnie wszystkie dane z ostatniego strumienia zostały zebrane w kolekcję i zwrócone.



3. Przekształcenie strumienia w zestaw

Tak wygląda typowa praca ze strumieniem i przekształcenie wyniku pracy w zestaw

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Cześć", "Jak", "дела?");

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

Wszystko jest bardzo podobne do kodu konwersji strumienia na List, tylko używany jest inny obiekt kolektora, który zwraca metodętoSet();



4. Konwertuj strumień na mapę

Jednak konwersja strumienia na mapę jest nieco trudniejsza. W końcu każdy obiekt Map składa się z dwóch elementów – klucza i wartości. Musimy dowiedzieć się, jak zdefiniujemy klucz dla elementu strumienia i jak zdefiniujemy wartość.

Przykład.

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]) );

Przyjrzyjmy się, co się tutaj dzieje.

W pierwszym wierszu map(...)konwertujemy każdy ciąg na tablicę ciągów. Korzystając z metody split, dzielimy każdy ciąg na dwie równe części.

W drugiej linii - metodzie filter()- przepuszczamy przez filtr tylko te elementy tablicy, które zawierają dokładnie dwa elementy. Element d == 3został podzielony na tablicę trzech elementów i filtr zakończy się niepowodzeniem.

I wreszcie, w ostatnim wierszu, zamieniamy strumień na Map<String, String>. Do metody toMap()przekazywane są dwie funkcje . Dla każdego elementu strumienia pierwsza funkcja powinna zwrócić klucz , a druga wartość .

Pierwszy element tablicy („a”, „b”, „c”) będziemy mieć jako klucz, a drugi element tablicy jako wartości: „2”, „3”, „4”.



5. Konwertuj strumień na łańcuch

Innym ciekawym obiektem kolekcjonerskim jest Collectors.joining(). Konwertuje wszystkie elementy strumienia na typ Stringi łączy je w jeden ciąg. Przykład

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