1. Coletando elementos

Por fim, chegamos ao método mais interessante da Streamclasse, 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 collectorobjeto 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 collectortipo 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 Collectorsclasse serão suficientes.

classe de colecionadores

A Collectorsclasse tem vários métodos estáticos que retornam objetos coletores prontos — algo para cada ocasião. Aqui vamos considerar os mais importantes.

toList()
Um objeto que converte um fluxo em uma lista ( List<T>)
toSet()
Um objeto que converte um fluxo em um conjunto ( Set<T>)
toMap()
Um objeto que converte um stream em um map( Map<K, V>)
joining()
Concatena os elementos de um stream em uma única string
mapping()
Converte os elementos de uma string em umMap<K, V>
groupingBy()
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==3string é 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 Stringe 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(", ") );