1. Coletando elementos
Por fim, chegamos ao método mais interessante da Stream
classe, o collect()
método. Ele é usado para mover de fluxos para nossas coleções familiares — , List<T>
e outros.Set<T>
Map<T, R>
O collect()
método usa um collector
objeto especial como argumento. Esse objeto lê todos os dados do fluxo, converte-os em um tipo específico de coleção e os retorna. E então o próprio método collect retorna essa coleção.
Tudo isso é feito de maneira bastante engenhosa: o collector
tipo do objeto é Collector<T, A, R>
. Como você pode ver, ele tem três parâmetros de tipo. O último parâmetro de tipo ( R
) geralmente é um tipo como List<T>
. Isso significa que o compilador pode usar esse tipo para determinar o tipo de retorno correto para o collect()
próprio método.
Espero que você não esteja muito confuso. De qualquer forma, você não precisa criar objetos Collector por conta própria. Os objetos prontos retornados pelos métodos estáticos da Collectors
classe serão suficientes.
classe de colecionadores
A Collectors
classe tem vários métodos estáticos que retornam objetos coletores prontos — algo para cada ocasião. Aqui vamos considerar os mais importantes.
|
Um objeto que converte um fluxo em uma lista ( List<T> ) |
|
Um objeto que converte um fluxo em um conjunto ( Set<T> ) |
|
Um objeto que converte um stream em um map( Map<K, V> ) |
|
Concatena os elementos de um stream em uma única string |
|
Converte os elementos de uma string em umMap<K, V> |
|
Agrupa os elementos e retornaMap<K, V> |
2. Convertendo um stream em uma lista
O seguinte é um exemplo típico de como trabalhar com um fluxo e converter o resultado em uma lista
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() );
Temos um fluxo da coleção. Em seguida, obtemos um novo fluxo retendo apenas as strings cujo primeiro caractere é maiúsculo. Em seguida, todos os dados desse fluxo são coletados em uma coleção, que é então retornada.
3. Convertendo um stream em um conjunto
O seguinte é um exemplo típico de como trabalhar com um fluxo e converter o resultado em um conjunto
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() );
Tudo é muito parecido com o código de conversão de um stream para um List
, só que usamos um objeto coletor diferente, que é retornado pelo toSet()
método.
4. Convertendo um fluxo em um mapa
Mas converter um fluxo em um mapa é um pouco mais difícil. Cada entrada em um mapa consiste em dois elementos: uma chave e um valor. Precisamos descobrir como definiremos a chave e o valor para cada elemento no fluxo.
Exemplo:
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]) );
Vamos dar uma olhada no que está acontecendo aqui.
Na primeira linha, usamos map(...)
para converter cada string em um array de strings. Usando o método split, dividimos cada string em duas partes.
Na segunda linha, passamos para o filter()
método apenas os arrays que contêm exatamente dois elementos. A d==3
string é dividida em uma matriz de três elementos, que não corresponde ao filtro.
E, finalmente, na última linha, convertemos o stream em um arquivo Map<String, String>
. Duas funções são passadas para o toMap()
método. Para cada elemento do stream, a primeira função deve retornar a chave e a segunda o valor .
O primeiro elemento de cada array ("a", "b", "c") será nossa chave, e o segundo elemento de cada array ("2", "3", "4") será nosso valor.
5. Convertendo um stream em uma string
Outro objeto coletor interessante é retornado por Collectors.joining()
. Ele converte todos os elementos de um fluxo String
e os concatena em uma única string. Exemplo
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