1. Събиране на елементи
Най-накрая стигнахме до най-интересния метод в Stream
класа, collect()
метода. Използва се за преминаване от потоци към познатите ни колекции — , List<T>
и други.Set<T>
Map<T, R>
Методът collect()
приема специален collector
обект като аргумент. Този обект чете всички данни от потока, преобразува ги в определен вид колекция и ги връща. И тогава самият метод collect връща тази колекция.
Всичко това се прави по доста хитър начин: collector
типът на обекта е Collector<T, A, R>
. Както можете да видите, той има три типа параметъра. Последният тип параметър ( R
) обикновено е тип като List<T>
. Това означава, че компилаторът може да използва този тип, за да определи правилния тип връщане за collect()
самия метод.
Надявам се, че не сте много объркан. Във всеки случай не е необходимо сами да създавате Collector обекти. Collectors
Ще бъдат достатъчни готовите обекти, върнати от статичните методи на класа.
Колекционерски клас
Класът Collectors
има няколко статични метода, които връщат готови обекти за събиране - нещо за всеки повод. Тук ще разгледаме най-важните.
|
Обект, който преобразува поток в списък ( List<T> ) |
|
Обект, който преобразува поток в набор ( Set<T> ) |
|
Обект, който преобразува поток в карта ( Map<K, V> ) |
|
Свързва елементите на поток в един низ |
|
Преобразува елементите на низ в aMap<K, V> |
|
Групира елементите и връщаMap<K, V> |
2. Преобразуване на поток в списък
Следва типичен пример за работа с поток и преобразуване на резултата в списък
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() );
Получихме поток от колекцията. След това получихме нов поток, като запазихме само низове, чийто първи знак е главна буква. След това всички данни от този поток се събират в колекция, която след това се връща.
3. Преобразуване на поток в набор
Следва типичен пример за работа с поток и преобразуване на резултата в набор
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() );
Всичко е много подобно на codeа за конвертиране на поток в List
, само че използваме различен колектор обект, който се връща от toSet()
метода.
4. Преобразуване на поток в карта
Но конвертирането на поток в карта е малко по-трудно. Всеки запис в карта се състои от два елемента: ключ и стойност. Трябва да разберем How ще дефинираме ключа и стойността за всеки елемент в потока.
Пример:
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]) );
Нека да разгледаме Howво става тук.
В първия ред използваме map(...)
за преобразуване на всеки низ в масив от низове. Използвайки метода на разделяне, ние разделяме всеки низ на две части.
Във втория ред предаваме на filter()
метода само тези масиви, които съдържат точно два елемента. Низът d==3
се разделя на масив от три елемента, който не отговаря на филтъра.
И накрая, в последния ред преобразуваме потока в Map<String, String>
. Към toMap()
метода се предават две функции. За всеки елемент от потока първата функция трябва да върне ключа , а втората връща стойността .
Първият елемент от всеки масив ("a", "b", "c") ще бъде нашият ключ, а вторият елемент от всеки масив ("2", "3", "4") ще бъде нашата стойност.
5. Преобразуване на поток в низ
Друг интересен колекционерски обект е върнат от Collectors.joining()
. Той преобразува всички елементи на поток в String
и ги свързва в един низ. Пример
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