Este tópico cobre os métodos de terminal da API de Streams, voltados para processamento, contagem, redução e agregação de dados. Aqui estão os métodos que você precisa conhecer:
📌 Principais métodos de dados e cálculo em Stream
| Método | Retorno | Descrição |
|---|---|---|
count() | long | Conta os elementos |
min(Comparator) | Optional<T> | Retorna o menor elemento |
max(Comparator) | Optional<T> | Retorna o maior elemento |
sum() | int, long, double | Soma (em streams primitivos) |
average() | OptionalDouble | Média (em streams primitivos) |
reduce(...) | Optional<T> ou T | Reduz os elementos a um só valor |
collect(...) | Variado | Coleta os elementos em estrutura (List, Set, Map etc.) |
🎯 Exemplos práticos
✔️ count()
long total = Stream.of("a", "b", "c").count();// 3
✔️ min() e max()
Optional<String> menor = Stream.of("leão", "tigre", "zebra")
.min((a, b) -> a.compareTo(b)); // leão
Optional<String> maior = Stream.of("leão", "tigre", "zebra")
.max(String::compareTo); // zebra
✔️ sum() e average() – Apenas em IntStream, DoubleStream ou LongStream
int soma = IntStream.of(10, 20, 30).sum();// 60
OptionalDouble media =IntStream.of(10, 20, 30).average();// 20.0
✔️ reduce() – Poderoso e versátil
Optional<String> resultado =Stream.of("J", "A", "V", "A")
.reduce((a, b) -> a + b); // JAVA
// Com valor inicial
String valor = Stream.of("J", "A", "V", "A")
.reduce("X", (a, b) -> a + b); // XJAVA
✔️ collect() – Usado para converter ou acumular os dados
List<String> lista = Stream.of("a", "b", "c")
.collect(Collectors.toList()); // [a, b, c]
String concatenado = Stream.of("a", "b", "c")
.collect(Collectors.joining()); // abc
😈 Pegadinhas que caem na prova
sum()eaverage()só existem em streams primitivos (IntStream,DoubleStream, etc.)reduce()com 2 argumentos (identidade,acumulador) retorna T, semOptional.min()/max()sempre exigem umComparator.collect()pode ser customizado comCollector.of(...)(avançado).count()sempre retornalong, nuncaint.
💡 Dica de prova
reduce()com 1 argumento → retornaOptional<T>.reduce()com 2 argumentos → retornaT.reduce()com 3 argumentos → usado em streams paralelos, retornaT.
Exemplos com pegadinhas e explicações
🔹 count() com filtro
long total = Stream.of("java", "python", "js")
.filter(s -> s.length() > 3)
.count(); // Resultado: 2
🔹 min() com Comparator
Optional<String> menor = Stream.of("ana", "bia", "carlos")
.min(Comparator.comparing(String::length)); // "ana"
🔹 reduce() sem identidade
Optional<Integer> resultado = Stream.of(1, 2, 3)
.reduce((a, b) -> a + b); // Optional[6]
🔹 reduce() com identidade
int soma = Stream.of(1, 2, 3)
.reduce(0, (a, b) -> a + b); // 6
🔹 reduce() com 3 argumentos (paralelismo)
int resultado = Stream.of(1, 2, 3)
.parallel()
.reduce(0, (a, b) -> a + b, (a, b) -> a + b); // 6
🔹 sum() e average()
IntStream s = IntStream.of(2, 4, 6);
System.out.println(s.sum());// 12
System.out.println(IntStream.of(2, 4, 6)
.average().getAsDouble());// 4.0
🔹 collect() com joining()
String result = Stream.of("J", "A", "V", "A")
.collect(Collectors.joining()); // "JAVA"
🔹 collect() para contar caracteres
Map<Integer, List<String>> agrupado =Stream.of("java", "js", "python")
.collect(Collectors.groupingBy(String::length));
🔹 collect() com mapping (avançado)
Map<Integer, Set<Character>> mapa = Stream.of("java", "jojo")
.collect(Collectors.groupingBy(
String::length,
Collectors.mapping(s -> s.charAt(0), Collectors.toSet())
));
Exercícios de múltipla escolha
❓ Questão 1
Qual método retorna Optional<T>?
A) count()
B) min()
C) sum()
D) collect()
❓ Questão 2
Qual a saída?
Stream<String> stream = Stream.of("a", "ab", "abc");
System.out.println(stream.filter(s -> s.length() > 1).count());
A) 3
B) 2
C) 1
D) Erro de compilação
❓ Questão 3
Qual código calcula corretamente a média?
A) Stream.of(1, 2, 3).average();
B) IntStream.of(1, 2, 3).average();
C) Stream.of("1", "2").mapToInt(Integer::parseInt).average();
D) B e C
❓ Questão 4
O que imprime?
Optional<Integer> o =Stream.of(1, 2, 3).reduce((a, b) -> a + b);
System.out.println(o.get());
A) 1
B) 6
C) 0
D) Erro
❓ Questão 5
Stream.of("a", "b", "c").collect(Collectors.joining()) retorna:
A) “abc”
B) Optional[abc]
C) [a, b, c]
D) Exception
❓ Questão 6
Qual dos métodos só existe em streams primitivos?
A) average()
B) reduce()
C) count()
D) collect()
❓ Questão 7
Dado:
Stream<String> s = Stream.of("carro", "casa", "cachorro");
System.out.println(s.min((a, b) -> a.compareTo(b)).get());
Resultado?
A) carro
B) cachorro
C) casa
D) Erro de compilação
❓ Questão 8
Em qual situação reduce() retorna um valor não Optional?
A) Quando usa 1 parâmetro
B) Quando usa 2 parâmetros
C) Quando usa collect()
D) Nunca retorna sem Optional
❓ Questão 9
Dado:
Stream<String> s = Stream.of("java", "python");
int soma = s.mapToInt(String::length).sum();
Resultado de soma é:
A) 4
B) 6
C) 10
D) 12
❓ Questão 10
Qual alternativa representa corretamente o uso de reduce() com 3 argumentos?
A) .reduce(a, b -> a + b)
B) .reduce(0, (a, b) -> a + b)
C) .reduce(0, (a, b) -> a + b, (a, b) -> a + b)
D) .reduce(Optional::get)
📘 Gabarito Comentado
- ✅ B –
min()emax()retornamOptional<T>. - ✅ B – Apenas “ab” e “abc” têm mais de 1 caractere → 2.
- ✅ D –
Streamcomum não temaverage(), masIntStreamtem. - ✅ B – Soma com
reduce()sem identidade retorna Optional[6]. - ✅ A –
joining()concatena sem delimitadores → “abc”. - ✅ A –
average()só existe emIntStream,DoubleStream, etc. - ✅ B – “cachorro” é menor que “carro” e “casa” lexicograficamente.
- ✅ B – Com identidade (
reduce(0, ...)), retorna valor direto. - ✅ C – “java” (4) + “python” (6) = 10.
- ✅ C – Forma completa de
reduce()usada para paralelismo.