Expressões Lambda
Funções de primeira classe e Streams API
Expressões lambda, introduzidas no Java 8, permitem tratar funções como objetos de primeira classe. Uma lambda é uma implementação inline e concisa de uma interface funcional — uma interface com apenas um método abstrato (@FunctionalInterface), como Runnable, Comparator, Predicate ou Function.
A sintaxe é: (parâmetros) -> expressão para corpo simples, ou (parâmetros) -> { statements } para múltiplas instruções. Com um parâmetro, os parênteses são opcionais. Com corpo de uma expressão, return e chaves são opcionais. Method references (Classe::metodo) são lambdas ainda mais concisas quando a lambda apenas delega para um método existente.
Lambdas combinadas com a Streams API transformam operações imperativas sobre coleções em pipelines declarativos: filter para filtrar, map para transformar, reduce para agregar, collect para materializar resultados.
import java.util.*;
import java.util.stream.*;
import java.util.function.*;
List<String> nomes = Arrays.asList("Ana", "Carlos", "Beatriz", "Davi", "Eve");
// ── Comparator com lambda ─────────────────────────
nomes.sort((a, b) -> a.compareTo(b)); // ordena alfabeticamente
nomes.sort(String::compareTo); // method reference equivalente
// ── Streams + Lambda ──────────────────────────────
List<String> resultado = nomes.stream()
.filter(n -> n.length() > 3) // filtra > 3 letras
.map(String::toUpperCase) // converte para maiúsculo
.sorted() // ordena
.collect(Collectors.toList());
System.out.println(resultado); // [BEATRIZ, CARLOS, DAVI]
// ── Interfaces funcionais ─────────────────────────
Predicate<Integer> ehPar = n -> n % 2 == 0;
Function<String, Integer> tamanho = String::length;
Consumer<String> imprimir = System.out::println;
Supplier<List<String>> novaLista = ArrayList::new;
System.out.println(ehPar.test(4)); // true
System.out.println(tamanho.apply("Java")); // 4
nomes.forEach(imprimir); // imprime cada nomeLambdas capturam variáveis do escopo externo, mas estas devem ser effectively final — não podem ser reatribuídas após a captura. Isso evita problemas de concorrência.