(Filtrar coleções usando expressões lambda)
🧠 Conceito-chave:
Você pode usar lambda expressions com Streams para filtrar elementos de uma coleção com base em uma condição.
✅ Exemplo básico
List<String> nomes =
Arrays.asList("Ana", "Bruno", "Alice", "Carlos");
List<String> nomesComA = nomes.stream()
.filter(nome -> nome.startsWith("A"))
.collect(Collectors.toList());
System.out.println(nomesComA);
// [Ana, Alice]
Explicações:
stream()cria o fluxo da listafilter()recebe umPredicate<T>→ função que retorna boolean- A expressão
nome -> nome.startsWith("A")filtra nomes que começam com “A” collect(Collectors.toList())transforma o resultado de volta em lista
🔍 Mais exemplos
1. Filtrar números pares:
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> pares = numeros.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
System.out.println(pares);
// [2, 4, 6]
2. Filtrar objetos:
class Pessoa {
String nome;
int idade;
Pessoa(String nome, int idade) {
this.nome = nome;
this.idade = idade;
}
public String toString() {
return nome + " (" + idade + ")";
}
}
List<Pessoa> pessoas = Arrays.asList(
new Pessoa("Ana", 17),
new Pessoa("Carlos", 20),
new Pessoa("Julia", 16)
);
List<Pessoa> adultos = pessoas.stream()
.filter(p -> p.idade >= 18)
.collect(Collectors.toList());
System.out.println(adultos);
// Carlos (20)
❌ Formas incorretas (pegadinhas)
// Erro: filter espera uma função que retorna boolean
.filter(n -> n + 1) // ❌ não retorna boolean
// Erro: tentar reusar a stream
Stream<String> s = nomes.stream();
s.filter(n -> n.length() > 3);
s.forEach(System.out::println); // ❌ IllegalStateException
🧪 Quiz com 5 questões
1) O que o método filter() espera como argumento?
A) Function
B) Predicate
C) Consumer
D) Supplier
2) O que retorna esse código?
List<String> lista = Arrays.asList("um", "dois", "três");
long count = lista.stream().filter(s -> s.length() > 3).count();
System.out.println(count);
A) 0
B) 1
C) 2
D) 3
3) Qual resultado da filtragem abaixo?
List<Integer> nums = Arrays.asList(2, 4, 6, 8);
List<Integer> res = nums.stream()
.filter(n -> n < 6)
.collect(Collectors.toList());
A) [6, 8]
B) [2, 4]
C) [4, 6]
D) [2, 4, 6]
4) Qual interface funcional é usada por .filter()?
A) BiFunction
B) Predicate
C) Comparator
D) Function
5) O que acontece se .filter() for chamado sem operação terminal?
A) A filtragem será aplicada normalmente
B) Um erro será lançado
C) Nada acontece
D) O código não compila
✅ Gabarito comentado
- B –
filter()espera umPredicate<T>, que retornatrueoufalse - C – “dois” e “três” têm mais de 3 letras
- B – apenas números menores que 6: 2 e 4
- B –
Predicate<T>é a interface usada - C – Streams são lazy, sem terminal nada acontece
📌 Resumo
.filter()recebe um lambda que retorna boolean (Predicate<T>)- Só é executado se tiver uma operação terminal
- Pode ser usado para filtrar elementos com base em qualquer regra
- Muito usado com
.collect(),.count(),.forEach()