Item 45: Seja criterioso ao utilizar as streams
Java Efetivo (livro)
Posted on July 25, 2024
- Resumo
API de Streams no Java 8:
Facilita operações em massa, sequenciais ou paralelas.
Duas principais abstrações: stream (sequência de elementos) e stream pipeline (cálculo de várias etapas).
Origem dos Elementos:
- Coleções, arrays, arquivos, regex, geradores de números aleatórios, outras streams.
- Suporte para referências de objetos e tipos primitivos (int, long, double).
Componentes de uma Stream Pipeline:
Stream de origem: ponto inicial.
Operações intermediárias: transformam a stream (ex.: map, filter).
Operação terminal: finaliza o processamento (ex.: collect, forEach).
Avaliação Preguiçosa:
A avaliação começa apenas na operação terminal.
Permite trabalhar com streams infinitas.
Pipelines sem operação terminal não fazem nada.
Fluência e Encadeamento:
API fluente permite encadear chamadas em uma única expressão.
Execução Paralela:
Pode ser ativada com parallel(), mas é raramente recomendada.
Cuidado no Uso de Streams:
Podem tornar o código curto e limpo, mas também ilegível e difícil de manter se usadas indevidamente.
Exemplo de Uso:
Comparação entre soluções com streams e iteração para encontrar anagramas.
Uso de computeIfAbsent para simplificar maps com múltiplos valores por chave.
Nomeação Criteriosa:
Nomes de parâmetros lambda são importantes para a legibilidade.
Quando Usar Streams:
Para tarefas como transformação, filtragem, combinação, acumulação e busca de elementos.
Limitações das Streams:
Difícil acessar elementos correspondentes de múltiplos estágios.
Complicado processar valores primitivos como char.
Escolha entre Streams e Iteração:
Não há regra fixa; escolha com base na clareza, manutenção e preferência de equipe.
Algumas tarefas são mais adequadas para streams, outras para iteração, e outras ainda para uma combinação de ambas.
Conclusão:
Use streams quando forem a melhor ferramenta para o trabalho, mas seja criterioso para evitar complicar o código.
Se você não tem certeza se uma tarefa é melhor atendida por
uma stream ou por uma iteração, tente usar as duas e veja qual delas
funciona melhor
Exemplos do Livro
Anagramas em Streams:
O programa lê palavras de um arquivo e organiza anagramas, palavras com as mesmas letras em ordem diferente.
Usa computeIfAbsent para mapear palavras para uma lista de anagramas.
Três versões do programa:
Versão 1 (iterativa): Usa loops para construir um map de anagramas.
Versão 2 (streams intensivo): Usa uma pipeline de streams para realizar o mesmo trabalho.
Versão 3 (híbrido): Combina streams e loops, resultando em um código mais claro e conciso.
Ver exemplo: Anagramas.java
Manuseio de Caracteres com Streams:
Demonstração de problemas ao usar streams para processar char.
Exemplo: “Hello world!”.chars() retorna uma stream de int, não char.
Necessidade de conversão para o tipo correto.
Primos de Mersenne:
Exibe os primeiros 20 primos de Mersenne.
Uso de Stream.iterate para gerar números primos.
Mostra como acessar valores anteriores na pipeline para exibir o expoente junto com o primo de Mersenne.
Ver exemplo StreamExamples.java
Inicialização de um Baralho de Cartas:
Dois métodos para inicializar um baralho:
Versão iterativa: Usa loops for-each aninhados.
Versão com streams: Usa flatMap para criar o produto cartesiano de Rank e Suit.
Discussão sobre qual abordagem é mais clara e preferível, dependendo da familiaridade da equipe com streams e programação funcional.
Esses exemplos mostram a versatilidade e as limitações das streams, além de enfatizar a importância de escolher a abordagem mais adequada para cada caso.
Ver exemplo DeckInicialization.java
Posted on July 25, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 28, 2024