Explicação: Java Streams é uma API introduzida no Java 8 para processar coleções de dados de forma declarativa e funcional. Ela permite operações como filtragem, mapeamento, ordenação e redução de dados de maneira eficiente.
Características principais:
- Não altera a coleção original: Streams operam sobre uma cópia dos dados.
- Operações intermediárias e terminais: As operações intermediárias (como
filter
emap
) são lazy, ou seja, só são executadas quando uma operação terminal (comocollect
ouforEach
) é chamada. - Programação funcional: Utiliza expressões lambda para simplificar o código.
Exemplo básico:
List<String> nomes = Arrays.asList("Ana", "João", "Maria", "Pedro");
nomes.stream()
.filter(nome -> nome.startsWith("A"))
.forEach(System.out::println);
// Saída: Ana
Exercício 1: Crie uma lista de números inteiros e use Streams para imprimir apenas os números pares.
Explicação: Operações intermediárias transformam ou filtram os dados, mas não executam o processamento até que uma operação terminal seja chamada.
Principais operações intermediárias:
filter(Predicate<T>)
: Filtra elementos com base em uma condição.map(Function<T, R>)
: Transforma cada elemento em outro tipo de dado.sorted()
: Ordena os elementos.distinct()
: Remove elementos duplicados.
Exemplo:
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6);
numeros.stream()
.filter(n -> n % 2 == 0) // Filtra pares
.map(n -> n * 2) // Multiplica por 2
.forEach(System.out::println);
// Saída: 4, 8, 12
Exercício 2:
Dada uma lista de strings, use filter
para encontrar palavras com mais de 5 caracteres e map
para convertê-las em maiúsculas.
Explicação: Operações terminais produzem um resultado final ou um efeito colateral, como imprimir valores ou coletar dados em uma nova coleção.
Principais operações terminais:
forEach(Consumer<T>)
: Executa uma ação para cada elemento.collect(Collector<T>)
: Coleta os elementos em uma coleção.reduce()
: Combina os elementos em um único valor.count()
: Retorna a quantidade de elementos.
Exemplo:
List<String> palavras = Arrays.asList("java", "stream", "api", "exemplo");
long count = palavras.stream()
.filter(p -> p.length() > 3)
.count();
System.out.println("Quantidade: " + count);
// Saída: Quantidade: 3
Exercício 3:
Crie uma lista de números e use reduce
para calcular a soma de todos os elementos.
Explicação:
O método collect
é usado para transformar o Stream em uma coleção ou outro tipo de dado.
Exemplos comuns:
Collectors.toList()
: Coleta os elementos em uma lista.Collectors.toSet()
: Coleta os elementos em um conjunto (sem duplicatas).Collectors.joining()
: Concatena strings.
Exemplo:
List<String> frutas = Arrays.asList("maçã", "banana", "laranja", "maçã");
Set<String> semDuplicatas = frutas.stream()
.collect(Collectors.toSet());
System.out.println(semDuplicatas);
// Saída: [maçã, banana, laranja]
Exercício 4:
Dada uma lista de nomes, use collect
para criar uma única string com todos os nomes separados por vírgulas.
Explicação:
Java Streams também suporta operações com tipos primitivos (int
, long
, double
) através de classes como IntStream
, LongStream
e DoubleStream
.
Exemplo:
IntStream.range(1, 6) // Cria um Stream de 1 a 5
.forEach(System.out::println);
// Saída: 1, 2, 3, 4, 5
Exercício 5:
Use IntStream
para gerar os primeiros 10 números pares e imprimi-los.
Explicação:
Streams podem ser processados em paralelo para melhorar o desempenho em grandes volumes de dados. Basta usar o método parallelStream()
.
Exemplo:
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
numeros.parallelStream()
.filter(n -> n % 2 == 0)
.forEach(System.out::println);
// Saída: Números pares em ordem não determinística
Exercício 6:
Crie uma lista de 1000 números aleatórios e use parallelStream
para encontrar o maior número.
- Dada uma lista de pessoas (nome e idade), use Streams para:
- Filtrar pessoas com mais de 18 anos.
- Mapear para uma lista de nomes.
- Ordenar os nomes alfabeticamente.
- Crie um Stream de números inteiros e calcule a média dos números maiores que 50.
- Use
Collectors.groupingBy
para agrupar uma lista de palavras pelo seu tamanho.