Interfaces Funcionais no Java
Tags: java, backend, backenddevelopment, poo
Published: 2023-08-07 14:25:17

Interfaces Funcionais são interfaces que contém apenas um método abstrato. Elas podem possuir qualquer quantidade de métodos padrão e estáticos, mas apenas um único método abstrato. São utilizadas em expressões lambda e referências a métodos, justamente pela característica de ter apenas um método abstrato, ou seja, quando implementamos um método de uma interface funcional o compilador consegue identificar que estamos nos referindo ao método abstrato da interface funcional em questão.

Qualquer interface que se encaixe no critério mencionado é considerada uma interface funcional. Entretanto, podemos deixar isso mais explícito ao compilador com a anotação @FunctionalInterface em cima da interface. Essa anotação não é obrigatória, mas nos resguarda de erros: Se anotamos uma interface com @FunctionalInterface e por algum motivo acidental criarmos mais de um método abstrato na interface, o compilador já irá identificar um erro e nos avisará que a interface em questão só pode ter um método abstrato.

O java nos oferece por padrão algumas interfaces funcionais que são bastante úteis com lambdas, mas também podemos criar nossas próprias interfaces funcionais, basta seguirmos o critério de ter apenas um método abstrato.
Algumas interfaces funcionais bastante utilizadas são: Consumer, Predicate, Function e Supplier.

- Consumer: Aceita apenas um argumento (Generics) e não tem valor de retorno. 
- Bi-Consumer: Recebe dois argumentos e não têm valor de retorno. 
- Predicate : Aceita um único valor ou argumento e retorna uma resposta booleana (True/False). Pode ser implementada usando uma classe pelo implements.
- Bi-Predicate: Recebe dois argumentos e retorna um valor booleano.
- Function: Recebe um único argumento(Generics) e retorna um valor(Generics) após o processamento.
- Bi-Function: Recebe dois argumentos, enquanto Function aceita um argumento. 
- Unary Operator and Binary Operator: Existem também duas outras interfaces funcionais que são nomeadas como Operador Unário e Operador Binário. Ambos estendem a Function e a Bi-Function, respectivamente. Em palavras simples, o operador unário estende a Function e o operador binário estende a Bi-Function. 
- Supplier: Não recebe nenhuma entrada ou argumento e retorna uma única saída. Existem várias extensões da interface funcional Supplier, como BooleanSupplier, DoubleSupplier, LongSupplier e IntSupplier. O tipo de retorno de todas essas outras especializações são apenas suas primitivas correspondentes.

A interface funcional Predicate, por exemplo, é usada para testar uma condição em um objeto e retornar um valor booleano. No exemplo abaixo, vamos utilizar Predicate de duas formas: A primeira, para verificar se um número é maior que zero. Neste exemplo, definimos um Predicate chamado isGreaterThanZero que verifica se um número é maior que zero. Usamos o método test() do Predicate para testar a condição para diferentes números e imprimir o resultado booleano. 
Na segunda forma, temos uma lista de números contendo os números 1, 4 e 5 e utilizamos um predicate no método filter da classe Stream em uma função lambda, para filtrar os números pares (em que o resto da divisão por 2 é igual a 0).


![interfaces funcionais java](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ih6dpcc2hq6seg6xpzlm.png)



Lembrando que podemos usar as interfaces funcionais em contextos mais complexos e principalmente no uso de expressões lambda.