8.7 Streams primitivos e infinitos
Resumo: Streams primitivos e infinitos 1. Streams Primitivos Objetivo: Evitar boxing/unboxing desnecessários, melhorando desempenho. Tipos disponíveis: IntStream, LongStream, DoubleStream. Iteradores especializados: Exemplo: PrimitiveIterator.OfInt (retorna int com nextInt(), além de next() para Integer). Métodos úteis: range(inicio, fim): Gera sequência de números (ex: IntStream.range(0, 10)). mapToInt, mapToLong, mapToDouble: Convertem Stream para streams primitivos. boxed(): Converte um stream primitivo para Stream (ex: IntStream.generate(...).boxed()). 2. Streams Infinitos Criação via Supplier: Stream.generate(Supplier): Gera elementos indefinidamente (ex: números aleatórios). IntStream.generate(() -> random.nextInt()) Stream.iterate(seed, UnaryOperator): Gera sequências com base em um valor inicial (ex: números naturais). IntStream.iterate(0, x -> x + 1) Operações de curto-circuito: limit(n): Limita o stream a n elementos (ex: .limit(10)). findFirst(): Retorna o primeiro elemento que atende a uma condição (ex: .filter(f -> f > 100).findFirst()). anyMatch, allMatch, noneMatch: Interrompem o processamento assim que a condição é resolvida. 4. Cuidados e Observações Streams infinitos exigem operações de curto-circuito: Sem limit, findFirst ou anyMatch, operações como sum() ou collect() podem não terminar. Exemplo perigoso: allMatch(f -> f % 2 == 0) em um stream infinito de Fibonacci (pode rodar indefinidamente). Estado em Suppliers: Lambdas não permitem variáveis mutáveis. Para manter estado, use classes ou interfaces funcionais com atributos (ex: Fibonacci). Estado pode limitar paralelização, pois streams paralelos processam elementos de forma não sequencial. APIs existentes: Random.ints(): Retorna um IntStream infinito de números aleatórios. Files.lines(), Pattern.splitAsStream(): Fontes alternativas para streams. 5. Vantagens e Aplicações Eficiência: Streams primitivos evitam overhead de boxing. Flexibilidade: Streams infinitos permitem modelar sequências ilimitadas (ex: dados em tempo real, séries matemáticas). Integração com APIs: Métodos como limit e findFirst facilitam o trabalho com grandes volumes de dados. Ver exemplos práticos: StreamPrimitivosInfinitosTest

Resumo: Streams primitivos e infinitos
1. Streams Primitivos
- Objetivo: Evitar boxing/unboxing desnecessários, melhorando desempenho.
Tipos disponíveis:
- IntStream, LongStream, DoubleStream.
Iteradores especializados:
- Exemplo: PrimitiveIterator.OfInt (retorna int com nextInt(), além de next() para Integer).
Métodos úteis:
- range(inicio, fim): Gera sequência de números (ex: IntStream.range(0, 10)).
- mapToInt, mapToLong, mapToDouble: Convertem Stream para streams primitivos.
- boxed(): Converte um stream primitivo para Stream (ex: IntStream.generate(...).boxed()).
2. Streams Infinitos
Criação via Supplier:
Stream.generate(Supplier): Gera elementos indefinidamente (ex: números aleatórios).
IntStream.generate(() -> random.nextInt())
Stream.iterate(seed, UnaryOperator): Gera sequências com base em um valor inicial (ex: números naturais).
IntStream.iterate(0, x -> x + 1)
Operações de curto-circuito:
- limit(n): Limita o stream a n elementos (ex: .limit(10)).
- findFirst(): Retorna o primeiro elemento que atende a uma condição (ex: .filter(f -> f > 100).findFirst()).
- anyMatch, allMatch, noneMatch: Interrompem o processamento assim que a condição é resolvida.
4. Cuidados e Observações
Streams infinitos exigem operações de curto-circuito:
- Sem limit, findFirst ou anyMatch, operações como sum() ou collect() podem não terminar.
- Exemplo perigoso: allMatch(f -> f % 2 == 0) em um stream infinito de Fibonacci (pode rodar indefinidamente).
Estado em Suppliers:
- Lambdas não permitem variáveis mutáveis. Para manter estado, use classes ou interfaces funcionais com atributos (ex: Fibonacci).
- Estado pode limitar paralelização, pois streams paralelos processam elementos de forma não sequencial.
APIs existentes:
- Random.ints(): Retorna um IntStream infinito de números aleatórios.
- Files.lines(), Pattern.splitAsStream(): Fontes alternativas para streams.
5. Vantagens e Aplicações
- Eficiência: Streams primitivos evitam overhead de boxing.
- Flexibilidade: Streams infinitos permitem modelar sequências ilimitadas (ex: dados em tempo real, séries matemáticas).
- Integração com APIs: Métodos como limit e findFirst facilitam o trabalho com grandes volumes de dados.
Ver exemplos práticos: StreamPrimitivosInfinitosTest