DEV Community

FUNDAMENTOS JAVA
FUNDAMENTOS JAVA

Posted on

1

7 Streams e Collectors

1 Melhoria na Ordenação de Coleções

  • A ordenação de coleções foi aprimorada com novos recursos da linguagem a partir do Java 8.

  • O objetivo é tornar o código mais conciso e legível.

Exemplo: Ordenação e Modificação de Usuários

Código Moderno:

  • Ordena os usuários pelo número de pontos (ordem decrescente).

  • Seleciona os 10 primeiros e os torna moderadores.

  • Mais compacto e direto.

usuarios.sort(Comparator.comparing(Usuario::getPontos).reversed());
usuarios
.subList(0,10)
.forEach(Usuario::tornaModerador);

Arquivo: Seleciona10.java

Código Antigo (Pré-Java 8)

  • Uso explícito da interface Comparator para ordenar.

  • Inversão da lista após a ordenação.

  • Iteração manual para modificar os 10 primeiros usuários.

Collections.sort(usuarios, new Comparator<Usuario>() {
@Override
public int compare(Usuario u1, Usuario u2) {
return u1.getPontos() - u2.getPontos();
}
});
Collections.reverse(usuarios);
List<Usuario> top10 = usuarios.subList(0, 10);
for (Usuario usuario : top10) {
usuario.tornaModerador();
}

Arquivo: Seleciona10Antigo.java

2 Streams: tornando moderadores os usuários com mais de 100 pontos

Filtragem Tradicional em Java (Pré-Java 8):

  • Uso de um laço for para percorrer a coleção.

  • Aplicação de uma condição if para filtrar os elementos desejados.

  • Código imperativo e verboso, exigindo mais blocos de código para cada nova condição.

  • Exemplo para tornar moderadores os usuários com mais de 100 pontos:

for (Usuario usuario : usuarios) {
if (usuario.getPontos() > 100) {
usuario.tornaModerador();
}
}

Arquivo: Moderador100Ponto.java

A Falta do Método filter na API de Collections

  • Diferente de sort (presente em List) e forEach (presente em Iterable), filter não foi adicionado diretamente a Collection ou List.

  • Razões para essa decisão:

  • API de Collection já era grande e difícil de evoluir sem quebrar compatibilidade.

  • Padrão comum de uso identificava a necessidade de operações encadeadas.

  • Evitar a criação de variáveis intermediárias para armazenar resultados parciais.

Introdução ao Stream no Java 8

  • O Stream foi criado para trabalhar com coleções de forma funcional e fluente.

  • Não altera a coleção original e evita efeitos colaterais.

Criando um Stream a partir de uma Lista

  • Novo método stream() adicionado na interface Collection:

Stream<Usuario> stream = usuarios.stream();

  • O método filter() recebe um Predicate e permite filtrar elementos:

Stream<Usuario> stream = usuarios.stream()
.filter(u -> u.getPontos() > 100);

  • Pode ser simplificado removendo a variável intermediária:

usuarios.stream()
.filter(u -> u.getPontos() > 100);

Arquivo: Moderador100PontoStreams.java

Streams Não Modificam a Coleção Original

  • filter() e outros métodos de Stream não alteram a lista original.

  • Exemplo mostrando que a filtragem não afeta a lista original:

usuarios.stream()
.filter(u -> u.getPontos() > 100);
usuarios.forEach(System.out::println); // Exibe todos os usuários

  • Para aplicar a transformação corretamente, é necessário armazenar o novo Stream e processá-lo:

usuarios.stream()
.filter(u -> u.getPontos() > 100)
.forEach(System.out::println);

Arquivo: MantemOriginal.java

Stream Não é uma Coleção

  • Diferente de uma List, Stream não armazena dados.

  • Ele é mais parecido com um Iterator, processando elementos sob demanda.

  • Opera como um pipeline, permitindo encadeamento fluente de métodos.

Uso Fluente do Stream

  • Melhor prática: encadear diretamente as operações sem criar variáveis intermediárias:

usuarios.stream()
.filter(u -> u.getPontos() > 100)
.forEach(System.out::println);

  • O método forEach() retorna void, finalizando o fluxo do Stream.

  • Para novas operações, deve-se chamar stream() novamente.

Exemplo Completo: Filtrar e Tornar Usuários Moderadores

  • Código otimizado com Stream:

usuarios.stream()
.filter(u -> u.getPontos() > 100)
.forEach(Usuario::tornaModerador);

Arquivo: FiltraModerador.java

Uso de Method Reference no filter

  • Quando o filter chama um único método de uma classe, pode-se usar Method Reference:

usuarios.stream()
.filter(Usuario::isModerador);

Arquivo: FiltraModerador.java

Top comments (0)