Atualizado: 21/09/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Métodos da Stream API em Java: Sub-fluxos, Concatenação e Elementos Únicos

Além das operações básicas de filtragem e mapeamento, a Stream API oferece métodos para manipulações mais avançadas, como a criação de sub-fluxos baseados em condições, a combinação de múltiplos streams e a garantia da unicidade dos elementos.

Criando Sub-fluxos Condicionais

Os métodos takeWhile e dropWhile são operações intermediárias que permitem fatiar um stream com base em uma condição. Eles são particularmente úteis e eficientes em streams ordenados.

O Método takeWhile

O método takeWhile seleciona elementos de um stream enquanto uma condição for atendida. Sua característica principal é que ele encerra a operação assim que encontra o primeiro elemento que não satisfaz a condição.

import java.util.stream.Stream;

// ...

Stream<Integer> numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5);
numbers.sorted() // É crucial ordenar o stream primeiro
       .takeWhile(n -> n < 0)
       .forEach(n -> System.out.println(n));

Com o stream ordenado, o resultado será -5, -4, -3, -2, -1.

Essa característica de "curto-circuito"(short-circuiting) torna takeWhile muito mais eficiente que filter em streams grandes e ordenados, pois ele não precisa percorrer todos os elementos.

O Método dropWhile

O método dropWhile executa a tarefa oposta: ele descarta os elementos do stream enquanto a condição for atendida. Assim que encontra o primeiro elemento que não satisfaz a condição, ele para de descartar e retorna o restante do stream.

Stream<Integer> numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5);
numbers.sorted()
       .dropWhile(n -> n < 0)
       .forEach(n -> System.out.println(n));

O resultado será 0, 1, 2, 3, pois todos os números negativos no início do stream ordenado foram descartados.

Modificando a Composição do Stream

O Método concat

O método estático Stream.concat() une os elementos de dois streams, retornando um novo stream que contém todos os elementos do primeiro, seguidos por todos os elementos do segundo. As fontes originais não são modificadas.

Stream<String> people1 = Stream.of("Tom", "Bob", "Sam");
Stream<String> people2 = Stream.of("Alice", "Kate", "Sam");

Stream.concat(people1, people2)
      .forEach(n -> System.out.println(n));

O resultado será:

Tom
Bob
Sam
Alice
Kate
Sam

Combinando Múltiplos Streams

Para combinar mais de dois streams, o concat se torna verboso. Uma abordagem mais flexível é usar Stream.of para criar um stream de streams e, em seguida, achatá-lo com flatMap.

Stream<String> people1 = Stream.of("Tom", "Bob");
Stream<String> people2 = Stream.of("Alice", "Kate");
Stream<String> people3 = Stream.of("Sam", "John");

Stream.of(people1, people2, people3)
      .flatMap(s -> s)
      .forEach(System.out::println);

O resultado será:

Tom
Bob
Alice
Kate
Sam
John

O Método distinct

O método distinct() é uma operação intermediária que retorna um novo stream contendo apenas os elementos únicos do stream original.

Stream<String> people = Stream.of("Tom", "Bob", "Sam", "Tom", "Alice", "Kate", "Sam");

people.distinct()
      .forEach(p -> System.out.println(p));

As duplicatas de "Tom" e "Sam" são removidas, resultando na saída:

Tom
Bob
Sam
Alice
Kate

Distinct com Objetos Customizados

É fundamental lembrar que a unicidade é determinada com base nos métodos equals() e hashCode() dos objetos. Se distinct() for usado em um stream de objetos de uma classe customizada (como a classe Phone nos temas anteriores), é essencial que essa classe sobrescreva adequadamente equals() e hashCode(). Sem isso, distinct() comparará as referências de memória dos objetos, e não seus valores, provavelmente não removendo duplicatas como o esperado.

Resumo

  • takeWhile(condition): Retorna os elementos do início do stream enquanto a condição for verdadeira; para no primeiro elemento falso. É eficiente em streams ordenados.
  • dropWhile(condition): Descarta os elementos do início do stream enquanto a condição for verdadeira e retorna o restante.
  • Stream.concat(stream1, stream2): Cria um novo stream unindo dois streams existentes. Para unir mais de dois, o padrão Stream.of(...).flatMap(...) é preferível.
  • distinct(): Retorna um stream contendo apenas os elementos únicos. Para objetos customizados, requer uma implementação correta dos métodos equals() e hashCode().
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com