21. Streams e a API de Stream em Java

A API de Stream em Java é uma abordagem moderna e funcional para processar sequências de elementos. Introduzida no Java 8, a API de Stream representa uma grande mudança na maneira como os desenvolvedores podem escrever código conciso e legível para manipular coleções de dados. Neste capítulo, vamos explorar o poder dos Streams, desde os conceitos básicos até técnicas avançadas.

Introdução aos Streams

Streams são abstrações que permitem processar elementos de uma coleção de maneira declarativa. Em vez de iterar explicitamente sobre uma coleção usando loops, você pode usar a API de Stream para descrever o que deseja fazer com esses elementos. A API de Stream suporta operações de agregação como filter, map, reduce e muitas outras.

Criando Streams

Você pode criar um Stream de várias maneiras. Uma das formas mais comuns é a partir de coleções, chamando o método stream():

List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
Outra maneira é usar métodos estáticos da classe Stream para criar streams de arrays ou valores específicos:
Stream<Integer> numberStream = Stream.of(1, 2, 3, 4, 5);
IntStream intStream = Arrays.stream(new int[] {1, 2, 3, 4, 5});

Operações Intermediárias

Operações intermediárias são aquelas que transformam um Stream em outro Stream, como filter, map e sorted. Elas são preguiçosas, o que significa que não são executadas até que uma operação terminal seja invocada.

  • filter: Seleciona elementos que atendem a um critério específico.
    stream.filter(s -> s.startsWith("a"));
    
  • map: Aplica uma função a cada elemento e retorna um Stream com os resultados.
    stream.map(String::toUpperCase);
    
  • sorted: Ordena os elementos de acordo com a ordem natural ou um Comparator fornecido.
    stream.sorted(Comparator.naturalOrder());
    

Operações Terminais

Operações terminais são aquelas que produzem um resultado ou efeito colateral, como forEach, collect, reduce e count. Quando uma operação terminal é invocada, o processamento do Stream é iniciado.

  • forEach: Executa uma ação para cada elemento do Stream.
    stream.forEach(System.out::println);
    
  • collect: Coleta os elementos do Stream em uma coleção ou outro tipo de resultado.
    List<String> collected = stream.collect(Collectors.toList());
    
  • reduce: Combina os elementos do Stream para produzir um único valor.
    Optional<String> concatenated = stream.reduce(String::concat);
    
  • count: Retorna o número de elementos no Stream.
    long count = stream.count();
    

Streams Paralelos

Streams paralelos permitem que as operações sejam executadas em paralelo em diferentes threads, o que pode levar a um melhor desempenho em sistemas com múltiplos processadores. Para criar um Stream paralelo, você pode chamar o método parallelStream() em uma coleção ou o método parallel() em um Stream existente.

Stream<String> parallelStream = list.parallelStream();

Considerações de Desempenho

Ao usar Streams, é importante estar ciente das implicações de desempenho. Operações como sorted e distinct podem ser custosas, pois requerem processamento adicional. Além disso, o uso de Streams paralelos nem sempre garante um aumento de desempenho e pode até ser contraproducente se o custo de divisão e fusão das tarefas for maior do que o ganho de processamento paralelo.

Boas Práticas

Quando se trabalha com Streams, é essencial seguir algumas boas práticas para manter o código limpo e eficiente:

  • Use métodos de referência sempre que possível para melhorar a legibilidade.
  • Evite alterar o estado de objetos externos dentro de operações de Stream.
  • Prefira operações sem estado, como map e filter, em vez de operações com estado, como sorted.
  • Considere a legibilidade e a manutenção do código em detrimento de micro-otimizações.

Conclusão

A API de Stream em Java oferece uma maneira poderosa e flexível de trabalhar com coleções de dados. Com uma ampla gama de operações intermediárias e terminais, os Streams permitem que os desenvolvedores escrevam código mais expressivo e conciso. Ao entender e aplicar corretamente os conceitos de Streams, você pode melhorar significativamente a qualidade e o desempenho do seu código Java.

Agora responda o exercício sobre o conteúdo:

Qual das seguintes afirmações sobre a API de Stream em Java é verdadeira?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

Imagem do artigo Concorrência e Threads em Java

Próxima página do Ebook Gratuito:

117Concorrência e Threads em Java

5 minutos

Ganhe seu Certificado deste Curso Gratuitamente! ao baixar o aplicativo Cursa e ler o ebook por lá. Disponível na Google Play ou App Store!

Disponível no Google Play Disponível no App Store

+ de 6,5 milhões
de alunos

Certificado Gratuito e
Válido em todo o Brasil

48 mil exercícios
gratuitos

4,8/5 classificação
nas lojas de apps

Cursos gratuitos em
vídeo, áudio e texto