Skip to content

Latest commit

 

History

History
143 lines (116 loc) · 7.38 KB

File metadata and controls

143 lines (116 loc) · 7.38 KB

Interfaces Funcionais (Functional Interfaces)

Objetivo
Define and write functional interfaces and describe the interfaces of the java.util.function package.
-
Definir e escrever interfaces funcionais e descrever as interfaces do pacote java.util.function.

Interfaces funcionais são um novo tipo de Interface do Java. Nesta seção serão apresentados os conceitos e na seção de Expressões Lambda será possível ver como utilizá-las.

  1. Interfaces Funcionais são aquelas que possuem apenas um método abstrato, chamado de "método funcional".

  2. É recomendada a utilização da anotação @FunctionalInterface, mas não obrigatório.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Basic.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Basic.java[role=include]

    A anotação @FunctionalInterface garante, em tempo de compilação, que esta interface é funcional. Também indica para outros desenvolvedores que ela foi criada com o intuito de ser utilizada em expressões lambda, e por isso não se deve criar outros métodos abstratos dentro dela.

  3. Métodos adicionais que sejam default ou static não fazem com que a interface deixe de ser funcional.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_DefaultStatic.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_DefaultStatic.java[role=include]

    Lembre-se que os métodos static em interfaces podem ser chamados diretamente, como Executavel.execute(…​). Dessa forma, não há interferência no fato da interface ser funcional.

    Por outro lado, os métodos default só podem ser chamados caso você possua uma instância da interface, porém eles já possuem uma implementação padrão.

    Em caso de dúvidas sobre static ou default em interfaces, volte na seção de "Métodos static e default em Interfaces".

  4. Sobrescrever na interface um método público de java.lang.Object também não faz com que ela deixe de ser funcional.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_OverrideObject.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_OverrideObject.java[role=include]
  5. Uma interface que estende outra sem acrescentar métodos abstratos também pode ser funcional.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Extends.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Extends.java[role=include]
  6. Se uma interface estende outra que é funcional, porém acrescenta novos métodos abstratos, ela não é funcional.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ExtendsNewMethod.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ExtendsNewMethod.java[role=include]
  7. Utilizar a anotação @FunctionalInterface em interfaces que possuem mais de um método abstrato causa um erro de compilação.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_InterfaceCompilationError.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_InterfaceCompilationError.java[role=include]
  8. Utilizar a anotaçao @FunctionalInterface em qualquer tipo que não seja uma interface causa um erro de compilação.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ClassCompilationError.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ClassCompilationError.java[role=include]
  9. Os métodos funcionais podem ter qualquer tipo de retorno.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ReturnType.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ReturnType.java[role=include]
  10. Interfaces funcionais são feitas com o intuito de serem utilizadas em expressões lambda, mas o código também irá compilar normalmente caso uma classe a implemente.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Implement.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Implement.java[role=include]

    Esse é apenas um exemplo para você saber que essa implementação não gera erro de compilação, mas não utilize interfaces funcionais dessa forma. Na seção de Expressões Lambda você verá como as interfaces funcionais devem ser utilizadas na prática.

Interfaces Funcionais do pacote java.util.function

As interfaces descritas aqui estão disponíveis no pacote java.util.function. Nesta seção serão apresentadas apenas suas definições, pois há posteriormente uma seção específica para tratar dos exemplos de cada uma.

Existem outras interfaces nesse pacote além das listadas aqui, porém são apenas específicas para lidar com tipos primitivos, seguindo as mesmas definições.

  • Supplier<T>: Representa um fornecedor de resultados.

    Um Supplier literalmente apenas fornece dados ou resultados para alguém. Um gerador de números sequenciais, por exemplo, pode ser um Supplier.

  • Consumer<T>: Representa uma operação que aceita uma única entrada e não possui retorno.

  • BiConsumer<T,U>: Representa uma operação que aceita duas entradas e não possui retorno.

    Os Consumer são praticamente o inverso dos Supplier, pois eles apenas recebem dados ou informações e os tratam de alguma forma.

  • Function<T,R>: Representa uma função que aceita um argumento e produz um retorno.

  • BiFunction<T,U,R>: Representa uma função que aceita dois argumentos e produz um retorno.

    As Function são mais parecidas com as funções que já conhecemos. Elas recebem dados e produzem um retorno.

  • Predicate<T>: Representa uma proposição (função de valor booleano) de um argumento.

  • BiPredicate<T,U>: Representa uma proposição (função de valor booleano) de dois argumentos.

    Os Predicate são parecidos com as Function, porém sempre retornam um resultado booleano, por isso são utilizados para "testes" de verdadeiro ou falso.

  • UnaryOperator<T>: Representa uma operação em um único operador que produz um resultado do mesmo tipo dele.

  • BinaryOperator<T>: Representa uma operação em dois operadores que produz um resultado do mesmo tipo deles.

    Os Operator são especializações de Function, pois apesar de também sempre recebem e produzirem resultados, as entradas e saídas são sempre do mesmo tipo.

Referências