Skip to content

Latest commit

 

History

History
141 lines (114 loc) · 6.92 KB

01-functional-interfaces.asc

File metadata and controls

141 lines (114 loc) · 6.92 KB

Functional Interfaces

Objective
Define and write functional interfaces and describe the interfaces of the java.util.function package.

Functional interfaces are a new type of Java Interface. In this section the concepts will be presented and in the Lambda Expressions section you will see how to use them.

  1. Functional Interfaces are those that have only one abstract method, called the "functional method".

  2. The use of the @FunctionalInterface annotation is recommended, but not required.

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

    The @FunctionalInterface annotation ensures at compile time that this interface is functional. It also indicates to other developers that it was created for use in lambda expressions, so you should not create other abstract methods within it.

  3. Additional methods that are default or static don’t make the interface to be functional.

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

    Remember that static methods on interfaces can be called directly, such as Executable.execute (…​). Thus, there is no interference in the fact that the interface is functional.

    On the other hand, default methods can only be called if you have an instance of the interface, but they already have a default implementation.

    If you have questions about static or default in interfaces, go back to the "Static and default methods of an interface" section.

  4. Overriding a public method of java.lang.Object in the interface doesn’t turn it to a no functional interface.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_OverrideObject.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_OverrideObject.java[role=include]
  5. An interface that extends another without adding abstract methods can also be functional.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Extends.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_Extends.java[role=include]
  6. If one interface extends another that is functional but adds new abstract methods, it is not functional.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ExtendsNewMethod.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ExtendsNewMethod.java[role=include]
  7. Using the @FunctionalInterface annotation on interfaces that have more than one abstract method causes a compilation error.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_InterfaceCompilationError.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_InterfaceCompilationError.java[role=include]
  8. Using the @FunctionalInterface annotation on any type other than an interface causes a compilation error.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ClassCompilationError.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ClassCompilationError.java[role=include]
  9. Functional methods can have any return.

    src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ReturnType.java
    link:../../../src/org/j6toj8/lambda/functionalinterfaces/FunctionalInterfaces_ReturnType.java[role=include]
  10. Functional interfaces are meant to be used in lambda expressions, but the code will also compile normally if a class implements it.

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

    This is just an example for you to know that this implementation does not generate compilation errors, but does not use functional interfaces in this way. In the Lambda Expressions section, you will see how functional interfaces should be used in practice.

Functional Interfaces from java.util.function package

The interfaces described here are available in the java.util.function package. This section will present only its definitions, as there is later a specific section to deal with the examples of each.

There are other interfaces in this package besides those listed here, but they are only specific to dealing with primitive types, following the same definitions.

  • Supplier<T>: Represents a results provider.

    A Supplier literally only provides data or results to someone. A sequential number generator, for example, may be a Supplier.

  • Consumer<T>: Represents an operation that accepts a single entry and has no return.

  • BiConsumer<T, U>: Represents an operation that accepts two inputs and has no return.

    Consumers are pretty much the opposite of Supplier, as they only receive data or information and treat them in some way.

  • Function<T, R>: Represents a function that accepts an argument and produces a return.

  • BiFunction<T, U, R>: Represents a function that takes two arguments and produces a return.

    The Function are more similar to the functions we already know. They receive data and produce a return.

  • Predicate<T>: Represents a proposition (Boolean value function) of an argument.

  • BiPredicate<T, U>: Represents a proposition (Boolean value function) of two arguments.

    Predicate is similar to Function, but always returns a Boolean result, so it is used for true or false "tests".

  • UnaryOperator<T>: Represents an operation on a single operator that produces a result of the same type as it.

  • BinaryOperator<T>: Represents an operation on two operators that produces a result of the same type as them.

    The Operator are Function specializations, because although they also always receive and produce results, the inputs and outputs are always the same type.

References