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има няколко статични метода, които връщат готови обекти за събиране - нещо за всеки повод. Тук ще разгледаме най-важните.

toList()
Обект, който преобразува поток в списък ( List<T>)
toSet()
Обект, който преобразува поток в набор ( Set<T>)
toMap()
Обект, който преобразува поток в карта ( Map<K, V>)
joining()
Свързва елементите на поток в един низ
mapping()
Преобразува елементите на низ в aMap<K, V>
groupingBy()
Групира елементите и връща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(", ") );