# Como usar Java collect() para coletar e processar dados

Stream Collectors são um recurso poderoso da **API Java 8 Stream**, capaz de coletar e processar dados de maneira eficiente. Conheça sua estrutura e como o método Java `collect()` pode ser utilizado.

## Como usar Java `collect()`?

Um Stream Collector pode ser usado para criar uma lista, um conjunto ou um mapa a partir de um stream. Um stream, por sua vez, é uma sequência de elementos processados um após o outro. A interface Collector oferece um conjunto de **operações de redução para dados** em um pipeline de stream, ou seja, operações terminais que coletam e mesclam resultados de etapas intermediárias.

Collectors podem ser usados para filtrar ou ordenar objetos de um stream. **Agregações** também são possíveis, como somar números, combinar strings ou contar elementos. Além disso, Collectors possuem funções que podem transformar o conteúdo de um stream em uma estrutura específica. Você pode, por exemplo, transformar uma lista em um mapa. Ainda, agrupamentos ajudam a categorizar elementos com certas propriedades ou condições.

O mais importante é que Stream Collectors têm a vantagem de **processar dados simultaneamente**, usando vários threads. Isso permite que operações sejam realizadas muito mais rapidamente e de forma eficiente, especialmente em grandes quantidades de dados.

## Qual é a sintaxe do Java `collect()`?

O método aceita um Collector como argumento, que descreve como os elementos do stream devem ser coletados e agregados. **Collector é uma interface** que fornece vários métodos para agregar elementos do stream de uma forma específica, como em uma lista, um conjunto ou um mapa.

Existem duas variantes do método Java Stream `collect()`:

1. &lt;R&gt; R collect(Supplier&lt;R&gt; supplier, BiConsumer&lt;R, ? super T&gt; accumulator, BiConsumer&lt;R, R&gt; combiner)
2. &lt;R, A&gt; R collect(Collector&lt;? super T, A, R&gt; collector)

A primeira variante tem três funções como argumentos:

- **supplier**: Cria um recipiente que será usado para resultados intermediários.
- **accumulator**: Calcula o resultado final.
- **combiner**: Combina os resultados de operações de stream paralelos.

Esses Collectors predefinidos já estão incluídos na biblioteca padrão e podem ser facilmente importados e usados.

A segunda variante aceita um Collector como argumento e retorna um resultado:

- **R**: O tipo de resultado.
- **T**: O tipo de elementos no stream.
- **A**: O tipo de acumulador que armazena o estado intermediário da operação do collector.
- **collector**: Executa a operação de redução.

Usando essa variante, os desenvolvedores podem criar **Collectors personalizados**, que são especificamente adaptados às suas necessidades, proporcionando maior flexibilidade e controle sobre o processo de redução.

## Exemplos práticos do uso do Java `collect()`

Abaixo, ilustramos várias funções do método `Stream.collect()`. Você deve se familiarizar com os [operadores em Java](https://www.ionos.com/digitalguide/websites/web-development/java-operators/ "Operadores em Java") básicos antes de se aprofundar no **framework de coleção**.

### Concatenar lista de strings

Com Java `collect()`, podemos **concatenar** uma lista de strings para obtermos uma nova string:

```Java
List<String> letras = List.of("a", "b", "c", "d", "e");
// sem função combiner
StringBuilder resultado = letras.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append("").append(b));
System.out.println(resultado.toString());
// com função combiner
StringBuilder resultado1 = letras.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append("").append(b));
System.out.println(resultado1.toString());
```

A saída é:

```Java
abcde
a b c d e
```

No primeiro cálculo, foi usada apenas uma instância de `StringBuilder` e nenhuma função `combiner`. Justamente por isso que o resultado exibido foi `abcde`.

Na segunda saída, a função `combiner` mesclou as instâncias de `StringBuilder` e as separou por vírgula.

### Coletar elementos em uma lista com `toList()`

Podemos usar a função `filter()` para selecionar certos elementos de uma lista e, em seguida, usar `toList()` para armazená-los em uma nova lista.

```Java
List<Integer> numeros = List.of(1, 2, 3, 4, 5, 6, 7);
List<Integer> numerosImpares = numeros.stream().filter(x -> x % 2 != 0).collect(Collectors.toList());
System.out.println(numerosImpares);
```

A nova lista tem apenas números ímpares:

```Java
[1, 3, 5, 7]
```

### Coletar elementos em um conjunto com `toSet()`

Da mesma forma, podemos selecionar elementos para criar um novo conjunto a partir deles. Elementos em um conjunto **não precisam ser dispostos em uma ordem específica**.

```Java
List<Integer> numeros = List.of(1, 2, 3, 4, 5, 6, 7);
Set<Integer> numerosPares = numeros.parallelStream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
System.out.println(numerosPares);
```

O código exibe a seguinte saída:

```Java
[2, 4, 6]
```

### Coletar elementos em um mapa com `toMap()`

Um mapa pode ser usado juntamente com o Java `collect()` para atribuir um valor a cada chave.

```Java
List<Integer> numeros = List.of(1, 2, 3, 4, 5, 6, 7);
Map<Integer, String> mapaNumerosPares = numeros.parallelStream().filter(x -> x % 2 == 0)
    .collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x)));
System.out.println(mapaNumerosPares);
```

Na saída, podemos observar que cada número par de entrada foi atribuído a um valor idêntico:

```Java
{2=2, 4=4, 6=6}
```

### Combinar elementos em uma string com `joining()`

O método `joining()` combina elementos de um stream na ordem em que aparecem, usando um **separador para separar os elementos**. O separador é passado como argumento para `joining()`. Se nenhum separador for especificado, `joining()` usará a string vazia `""`.

```Java
jshell> String resultado1 = Stream.of("a", "b", "c").collect(Collectors.joining());
jshell> String resultado2 = Stream.of("a", "b", "c").collect(Collectors.joining("", "{", "}"));
```

Os resultados obtidos são:

```Java
resultado1 ==> "abc"
resultado2 ==> "{abc}"
```


This is a markdown version of: [https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/java-stream-collect/](https://www.ionos.com/pt-br/digitalguide/sites-de-internet/desenvolvimento-web/java-stream-collect/) for AI/LLM consumption.