Programação Funcional em Java: Guia Completo de A a Z

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Programação Funcional em Java: de A a Z



Programação Funcional (PF) é um paradigma onde os cálculos são tratados como avaliação de funções matemáticas, evitando mudanças de estado e dados mutáveis. O Java, tradicionalmente uma linguagem imperativa, a partir da versão 8, incorpora ativamente elementos de PF. Isso permite escrever código mais conciso, previsível e facilmente testável, especialmente ao trabalhar com coleções e operações assíncronas.



Neste artigo, abordaremos os conceitos-chave de PF em Java: desde expressões lambda até técnicas avançadas de trabalho com Stream API e Optional. Você aprenderá como aplicar essas ferramentas na prática para que seu código se torne mais limpo e eficiente.



1. Fundamentos: Expressões Lambda e Interfaces Funcionais



Expressão lambda é uma forma concisa de escrever um método anônimo (função). Ela permite passar comportamento como dado. Sintaxe: (parâmetros) -> corpo.



Interface funcional é uma interface com um único método abstrato (SAM — Single Abstract Method). São essas interfaces que podem ser implementadas com lambdas. As principais interfaces embutidas em java.util.function:



  • Predicate<T> — recebe um objeto T, retorna boolean (método test).
  • Function<T, R> — recebe T, retorna R (método apply).
  • Consumer<T> — recebe T, não retorna nada (método accept).
  • Supplier<T> — não recebe nada, retorna T (método get).
  • UnaryOperator<T> — caso especial de Function, onde T e R são do mesmo tipo.


Exemplo: Ordenação de lista com Comparator (interface funcional)



import java.util.*;

public class LambdaExample { public static void main(String[] args) { List<String> names = Arrays.asList("Ivan", "Anna", "Pedro", "Maria");

// Sem lambda (classe anônima) Collections.sort(names, new Comparator<String>() { @Override public int compare(String a, String b) { return a.length() - b.length(); } });

// Com lambda Collections.sort(names, (a, b) -> a.length() - b.length());

// Ainda mais curto: usando Comparator.comparingInt names.sort(Comparator.comparingInt(String::length));

System.out.println(names); // [Anna, Pedro, Ivan, Maria] }}


Exemplo: Uso de Predicate para filtragem



import java.util.function.Predicate;

public class PredicateExample { public static void main(String[] args) { Predicate<Integer> isEven = n -> n % 2 == 0; Predicate<Integer> isPositive = n -> n > 0;

System.out.println(isEven.test(4)); // true System.out.println(isEven.and(isPositive).test(-2)); // false (não positivo) System.out.println(isEven.or(isPositive).test(-3)); // true (não é par, mas é positivo? não, -3 não é positivo) }}


2. Stream API: Poderosa ferramenta de processamento de dados



Stream API é uma sequência de elementos que suporta operações paralelas e sequenciais. Stream não armazena dados, mas os transforma. As principais operações são divididas em intermediárias (retornam um novo Stream) e terminais (finalizam o processamento e retornam um resultado ou efeito colateral).



Principais operações do Stream API:

  • Intermediárias: filter, map, flatMap, sorted, distinct, peek, limit, skip.
  • Terminais: collect

Blogs

Book Recommendations