Java Funções Intermediário
Lambdas
As lambdas são funções anônimas que podem ser passadas como argumentos ou armazenadas em variáveis. Elas permitem escrever código mais conciso e expressivo, especialmente ao trabalhar com interfaces funcionais — interfaces com um único método abstrato (SAM). A sintaxe básica é (parâmetros) -> expressão ou (parâmetros) -> { bloco de código }.
Lambdas só podem ser usadas onde se espera uma interface funcional. A anotação @FunctionalInterface ajuda o compilador a garantir que a interface tenha exatamente um método abstrato. Method references (Classe::metodo) são uma forma ainda mais enxuta de escrever lambdas que apenas chamam um método existente.
Lambdas podem capturar variáveis do escopo externo, mas essas variáveis precisam ser efetivamente finais (não podem ser reatribuídas após a captura). Isso garante segurança em ambientes concorrentes e evita efeitos colaterais inesperados.
Pontos-chave
- Lambdas implementam interfaces funcionais (um único método abstrato).
- A sintaxe pode omitir tipos e parênteses em casos simples:
x -> x * 2. - Method references (
String::length) substituem lambdas que só chamam um método. - Variáveis capturadas por lambdas devem ser efetivamente finais.
@FunctionalInterfacedocumenta e valida a intenção da interface.
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.function.Predicate;
public class ExemploLambdas {
public static void main(String[] args) {
List<String> nomes = Arrays.asList("Ana", "Bruno", "Carlos", "Diana");
// Lambda com expressão: filtra nomes com mais de 3 letras
Predicate<String> maisDeTres = s -> s.length() > 3;
nomes.stream()
.filter(maisDeTres)
.forEach(n -> System.out.println("Nome: " + n));
// Lambda com bloco: converte para maiúsculas
Function<String, String> maiuscula = s -> {
String resultado = s.toUpperCase();
return resultado;
};
System.out.println("Maiúscula: " + maiuscula.apply("java"));
// Method reference: imprime cada elemento
nomes.forEach(System.out::println);
// Captura de variável efetivamente final
String prefixo = "Sr(a). ";
nomes.forEach(nome -> System.out.println(prefixo + nome));
}
}