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