🎯 O que é uma expressão lambda?
É uma forma concisa de representar uma função anônima (sem nome) que pode ser passada como argumento para métodos, armazenada em variáveis ou usada para processamento funcional.
Uma lambda implementa uma interface funcional (aquela com um único método abstrato).
📘 Sintaxe básica
(parâmetros) -> expressão_ou_bloco
Exemplos:
(a, b) -> a + b
x -> x.toUpperCase()
() -> System.out.println("Olá")
🧪 Interface funcional usada nos exemplos
@FunctionalInterface
interface Operacao {
int calcular(int a, int b);
}
✅ Exemplos CORRETOS de uso
Operacao soma = (a, b) -> a + b;
Operacao sub = (int a, int b) -> a - b;
Operacao mult = (a, b) -> {
int resultado = a * b;
return resultado;
};
Runnable r = () -> System.out.println("Executando");
Runnable r2 = () -> {
System.out.println("Linha 1");
System.out.println("Linha 2");
};
📝 Explicação do código acima:
- Linha 1: lambda simples, inferência de tipo.
- Linha 2: lambda com tipos explícitos (válido).
- Linhas 3–6: lambda com bloco
{}exigereturne;(ponto e vírgula). - Linha 7:
Runnablenão recebe parâmetros. - Linhas 8–11: bloco multi-linha também exige
{}e;em cada instrução. Não esqueça do ponto final Linha 11.
❌ Exemplos INCORRETOS
Operacao o1 = (a, b) -> return a + b;
Operacao o2 = a, b -> a + b;
Operacao o3 = (a, b) -> { a + b; };
Runnable r = () -> System.out.println("Oi")
Operacao o4 = (a, b) -> { return a + b }
Operacao o5 = (int a, b) -> a + b;
📝 Explicação dos códigos acima:
- Linha 1: ERRO – não se pode usar
returnsem{}. - Linha 2: ERRO – precisa de parênteses em múltiplos parâmetros.
- Linha 3: ERRO – bloco
{}exigereturne;. - Linha 4: ERRO – falta
;no final. - Linha 5: ERRO – falta
;apósreturndentro de{}. - Linha 6: ERRO – ou todos os parâmetros têm tipo, ou nenhum.
✅ Lambda com coleções (muito usado!)
List<String> nomes = Arrays.asList("Ana", "Bruno", "Carlos");
nomes.forEach(n -> System.out.println(n));
nomes.sort((a, b) -> a.compareTo(b));
📝 Comentários:
- Linha 2:
forEachusa lambda como consumidor. - Linha 3:
sortusa lambda como comparador.
✅ Lambda com Predicate e Function
Predicate<String> ehVazia = s -> s.isEmpty();
Function<String, Integer> tamanho = s -> s.length();
📝 Comentários:
- Linha 1:
Predicaterecebe um parâmetro e retorna boolean. - Linha 2:
Function<T, R>recebe T e retorna R.
✅ Lambda como parâmetro de método
public static void executar(Operacao o) {
int resultado = o.calcular(10, 5);
System.out.println(resultado);
}
executar((a, b) -> a + b);
📝 Comentários:
- Linha 5: chamando o método
executarcom uma lambda como argumento.
⚠️ Pegadinhas comuns
- ❌ Usar
returnfora de blocos{}. - ❌ Usar
;no lugar errado. - ❌ Usar tipos diferentes nos parâmetros sem declarar todos.
- ❌ Usar interface com mais de um método abstrato (não é funcional).
📘 Interface funcional personalizada
@FunctionalInterface
interface Validador {
boolean validar(String s);
}
Validador v = s -> s.length() > 5;
System.out.println(v.validar("OCP"));
📚 Perguntas estilo 1Z0-809
1️⃣ Qual dessas expressões lambda é válida?
✅Gabarito: C, D
Explicação:
A) ❌ Inválido – múltiplos parâmetros sem parênteses não são permitidos.
B) ❌ Inválido – se um parâmetro tem tipo, todos devem ter.
C) ✅ Válido – sintaxe correta com parênteses e bloco com return.
D) ✅ Válido – lambda de um parâmetro com retorno em bloco.
A) x, y -> x + y
B) (int x, y) -> x + y
C) (x, y) -> { return x + y; }
D) x -> { return x; }
2️⃣ Qual é a saída?
✅Gabarito: B
✔️Explicação:
O filter remove “a” (tamanho 1), restando “bb” e “ccc”, que são impressos sem separador → bbccc
List<String> lista = Arrays.asList("a", "bb", "ccc");
lista.stream()
.filter(s -> s.length() > 1)
.forEach(System.out::print);
A) abc
B) bbccc
C) a
D) bbccc (sem nova linha)
3️⃣ O que está incorreto sobre expressões lambda?
✅Gabarito: C
✔️Explicação:
A) ✅ Lambdas podem ser atribuídas a variáveis.
B) ✅ Devem implementar interfaces funcionais.
C) ❌ Nem sempre precisam de return – se for uma expressão única, return é opcional.
D) ✅ Predicate e Function são usos clássicos de lambda.
A) Podem ser atribuídas a variáveis
B) Devem implementar interfaces com um único método abstrato
C) Sempre precisam ter return
D) Podem ser usadas com Predicate e Function
4️⃣ O que ocorre com esta expressão?
✅Gabarito: B – Falta ; no final da instrução.
✔️Explicação:
O código está dentro de um método e está faltando o ; no final da expressão lambda atribuída à variável r.
Runnable r = () -> {
System.out.println("Rodando");
}
A) Compila e executa
B) Falta ; no final
C) Precisa de return
D) Não é interface funcional
5️⃣ Qual uso de lambda é incorreto?
✅Gabarito: C
✔️Explicação:
A) ✅ (x) -> x.toUpperCase() – válido.
B) ✅ x -> { return x.toLowerCase(); } – válido, bloco com return.
C) ❌ x -> return x.length(); – inválido, pois usa return fora de bloco {}.
D) ✅ x -> x.length() – expressão simples.
A) (x) -> x.toUpperCase()
B) x -> { return x.toLowerCase(); }
C) x -> return x.length();
D) x -> x.length()
🧠 Resumo final do tópico: Lambda Expressions
- Lambdas são funções anônimas que implementam interfaces funcionais.
- A sintaxe varia de acordo com o número de parâmetros e o corpo (expressão única ou bloco).
- Usos comuns incluem
Runnable,Comparator,Predicate,Function,Consumer, entre outros. - Expressões lambda aumentam a legibilidade e reduzem a verbosidade do código.
- Sempre valide:
- Parênteses obrigatórios em múltiplos parâmetros.
returnsó dentro de blocos{}.- Tipagem de parâmetros deve ser uniforme.