Desafio Java
Calculadora funcional com interface personalizada e captura
Enunciado
Crie uma interface funcional Operacao com um método int aplicar(int a, int b). Implemente uma calculadora que recebe duas operações via lambda (soma e multiplicação) e as aplica a dois números. Além disso, capture uma variável fator para criar uma operação que multiplica por um valor fixo.
Requisitos
- Defina
@FunctionalInterfaceparaOperacao. - Use lambdas para soma e multiplicação.
- Capture uma variável
fator(efetivamente final) em uma lambda. - Imprima os resultados no formato especificado.
Código inicial
public class CalculadoraFuncional {
@FunctionalInterface
interface Operacao {
int aplicar(int a, int b);
}
public static void main(String[] args) {
// Seu código aqui
}
}
Saída esperada
Soma: 7
Multiplicação: 12
Multiplicado por 3: 15
Ver dica
Para capturar fator, defina int fator = 3; antes da lambda e use x -> x * fator.
Mostrar solução
public class CalculadoraFuncional {
@FunctionalInterface
interface Operacao {
int aplicar(int a, int b);
}
public static void main(String[] args) {
// Lambdas para operações básicas
Operacao soma = (a, b) -> a + b;
Operacao multiplicacao = (a, b) -> a * b;
System.out.println("Soma: " + soma.aplicar(3, 4));
System.out.println("Multiplicação: " + multiplicacao.aplicar(3, 4));
// Captura de variável efetivamente final
int fator = 3;
Operacao multiplicaPorFator = (a, b) -> a * fator; // b ignorado
System.out.println("Multiplicado por 3: " + multiplicaPorFator.aplicar(5, 0));
}
}
Passo a passo
- Declaramos a interface funcional
Operacaocom a anotação@FunctionalInterface, que garante um único método abstratoaplicar. - Criamos a lambda
somaque recebe dois inteiros e retorna a soma. Ela implementaOperacao. - Criamos a lambda
multiplicacaoque retorna o produto dos dois inteiros. - Chamamos
aplicarem cada operação e imprimimos os resultados formatados. - Definimos a variável local
fatorcom valor 3. Ela é efetivamente final (não é reatribuída). - Criamos a lambda
multiplicaPorFatorque ignora o segundo parâmetro e multiplica o primeiro porfator. Capturamosfatordo escopo externo. - Chamamos
aplicar(5, 0)e imprimimos o resultado.
Por que funciona
A anotação @FunctionalInterface permite que o compilador verifique se a interface tem exatamente um método abstrato, o que é pré-requisito para lambdas. As lambdas soma e multiplicacao fornecem implementações concisas para Operacao. A lambda multiplicaPorFator captura a variável fator, que é efetivamente final (não modificada após a inicialização). Isso é exigido pelo Java para evitar inconsistências em ambientes concorrentes e garantir que o valor capturado seja estável.
Erros comuns
- Tentar modificar
fatorapós a lambda:fator = 4;causaria erro de compilação: "local variables referenced from a lambda expression must be final or effectively final". - Esquecer a anotação
@FunctionalInterface: não é obrigatória, mas sem ela o compilador não avisa se alguém adicionar outro método abstrato, quebrando as lambdas. - Usar
bna lambda que ignora o segundo parâmetro: se escrever(a, b) -> a * fator, o parâmetrobnão é usado, mas isso é permitido. No entanto, se a intenção for ignorar, pode-se usar_(a partir do Java 21) ou simplesmente não usar. - Confundir method reference com lambda:
Operacao::somanão funcionaria aqui porquesomanão é um método estático acessível dessa forma; seria necessárioInteger::sumse fosse o caso.
Outra forma de resolver
Usar method references para operações da classe Integer:
Operacao soma = Integer::sum;
Operacao multiplicacao = (a, b) -> a * b; // não há method reference direto para multiplicação
Method references são preferíveis quando já existe um método estático ou de instância que faz exatamente o que a lambda faria.
Saída esperada
Soma: 7
Multiplicação: 12
Multiplicado por 3: 15