A Java Functional Interface is the one which can be used as Lambda expression. The requirement is, it should have only one abstract method. Java 8 introduced a new package : java.util.function. This package has many commonly used Functional Interfaces. Let's have a look at the package:
Important things:
Interface
Description
Function Method
Consumer<T>
Accepts a single input of type T and returns no values.
void accept(T t)
Supplier<T>
Accepts no inputs and returns a value of type T
T get()
Function<T,R>
Accepts input of type T and returns a value of type R
R apply(T t)
Predicate<T>
Accepts a single input argument of type T and returns boolean.
boolean test(T t)
BiXXX interfaces
The interfaces starting with Bi i.e. of form BiXXX are another versions of one of the above interfaces with one difference, they take two arguments of different type instead of one and returns no values. This doesn't apply to Supplier<T>, as it doesn't take any arguments but just returns(supplies) a type T.
UnaryOperator<T>
A special type of Function but accepts and returns the same type T
T apply(T t);
primitiveXXX type
The ones with starting with some primitive data type e.g. IntConsumer. They either accept or return primitive java type instead of some Object type.
The ones of form xxxToYyyFunction. Well, they are only another versions of Funtion but accepts some primitive type and return another primitive type.
BinaryOperator<T>
A special type of BiFunction but accepts two aruments of same type and returns the same type as well. T
T apply(T t, T u);
The ones of form ObjXxxConsumer<T>, are another version of consumers but requires two arguments, one of type T and another one is some primitive
If we going to create our own functional interface, we can put this optional java.lang.FunctionalInterface
on the type level. This is just an informative annotation and for the compile time strict checking.
If a type is annotated with this annotation type, Java compilers are required to generate an error message unless:
The type is an interface type and not an annotation type, enum, or class.
The annotated type satisfies the requirements of a functional interface, i.e. a functional interface should have
exactly one abstract method. It may have multiple default or static methods though.
However, the compiler will treat any interface meeting the definition of a functional interface as a functional
interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.