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 collector
ma typ Collector<T, A, R>
- ma już trzy parametry typu. Ostatnim typem R
jest 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 Collectors
posiada kilka metod statycznych, które zwracają gotowe obiekty kolekcjonerskie na każdą okazję. Jest ich kilkadziesiąt, ale rozważymy te najbardziej podstawowe:
|
Obiekt, który konwertuje strumień na listę −List<T> |
|
Obiekt, który konwertuje strumień na zbiór −Set<T> |
|
Obiekt, który konwertuje strumień na mapę −Map<K, V> |
|
Łączy elementy strumienia w jedną linię |
|
Konwertuje elementy strumienia naMap<K, V> |
|
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 == 3
został 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 String
i łą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(", ") );
GO TO FULL VERSION