Expressões Lambda representam uma forma concisa de implementar interfaces funcionais em Java. Elas permitem tratar código como dados, passando métodos como parâmetros de outros métodos.
Sintaxe Básica
A estrutura fundamental de uma expressão Lambda é:
<InterfaceFuncional> <nomeVariavel> = (<parametro1>, <parametro2>...) -> {
// Corpo do método
};
O operador seta -> divide a expressão em duas partes:
- Esquerda: A lista de parâmetros.
- Direita: O corpo do método.
Considerações Importanntes:
- Os tipos dos parâmetros são inferidos automaticamente pelo compilador.
- Se a lista de parâmetros estiver vazia, use apenas parênteses
(). - Se houver apenas um parâmetro, os parênteses podem ser omitidos, utilizando apenas o nome do parâmetro.
- Se o corpo do método contiver apenas uma instrução e não houver retorno, as chaves
{}e a palavra-chavereturnpodem ser omitidas. Se houver retorno, a omissão das chaves exige a omissão simultânea dereturn, e o corpo deve consistir em uma única expressão. - Expressões Lambda não geram arquivos de classe internos distintos.
Interfaces Funcionais
Uma interface é considerada funcionnal se possuir apenas um método abstrato. Essas interfaces são o alvo das expressões Lambda, que são mapeadas para o único método abstrato.
A anotação @FunctionalInterface pode ser utilizada para verificar se uma interface atende a esse critério.
Exemplo de Interface Funcional e Implementação:
// Definição da interface funcional
@FunctionalInterface
public interface Dispositivo {
void operar();
}
// Implementação utilizando expressão Lambda
public class TesteDispositivo {
public static void main(String[] args) {
// Implementação tradicional (sem Lambda)
Dispositivo mouseTradicional = new Dispositivo() {
@Override
public void operar() {
System.out.println("Mouse ativado.");
}
};
// Implementação com expressão Lambda
Dispositivo ventilador = () -> System.out.println("Ventilador ligado.");
executarOperacao(mouseTradicional);
executarOperacao(ventilador);
}
public static void executarOperacao(Dispositivo disp) {
disp.operar();
}
}
Referências a Métodos
Referências a métodos são uma forma abreviada de expressões Lambda. Quando o corpo de uma expressão Lambda consiste unicamente na invocação de um método existente, a referência a método pode ser usada.
Formas Comuns de Referência a Métodos:
objeto::metodoInstanciaClasse::metodoEstaticoClasse::metodoInstanciaClasse::new(para construtores)
Exemplo de Referências a Métodos:
import java.util.function.Consumer;
import java.util.function.Comparator;
import java.util.function.Function;
import java.util.function.Supplier;
// Classe de exemplo para demonstração
class Funcionario {
private String nome;
private double salario;
public Funcionario(String nome, double salario) {
this.nome = nome;
this.salario = salario;
}
public String getNome() {
return nome;
}
@Override
public String toString() {
return "Funcionario [nome=" + nome + ", salario=" + salario + "]";
}
}
public class TesteReferenciasMetodo {
public static void main(String[] args) {
// 1. Objeto::metodoInstancia
Consumer<String> impressor = System.out::println;
impressor.accept("Saudacao");
// 2. Classe::metodoEstatico
Comparator<Integer> comparadorInt = Integer::compare;
System.out.println("Comparacao: " + comparadorInt.compare(10, 5));
// 3. Classe::metodoInstancia
Function<Funcionario, String> extratorNome = Funcionario::getNome;
Funcionario f = new Funcionario("Ana Silva", 60000);
System.out.println("Nome do funcionario: " + extratorNome.apply(f));
// 4. Classe::new (referência a construtor)
Supplier<Funcionario> criadorFuncionario = Funcionario::new;
Funcionario novoFuncionario = criadorFuncionario.get(); // Chama o construtor padrão
System.out.println(novoFuncionario);
}
}