An interface that only contain one abstract method is called functional interface (A functional interface may contain one or more default methods or static methods). It can be called as Single Abstract Method (SAM) also.
We can use annotation @FunctionalInterface to declare functional interface. However, there are no issue if you don't use this annotation, using this annotation just ensures for compile process which will throw exception if there are 2 abstract methods.
Application.java
1234567
// functional interface without anotationpublicinterfaceApplication{publicStringgetApplicationId(StringappNumber);}
Application.java
12345678
// functional interface with anotation@FunctionalInterfacepublicinterfaceApplication{publicStringgetApplicationId(StringappNumber);}
The main benefit of java 8 functional interface is helping us can use Java 8 Lambda Expression to declare body method and avoid using anonymous class.
Java 8 collection API has been rewritten and new Stream API is introduced that uses a lot of functional interface in java.util.function package. Some of the useful java 8 function interface are list as in the table below.
Functional Interface
Description
Method Signature
Consumer
Represents an operation that accepts a single input argument of type T and returns no result.
void accept(T t)
Supplier
Represents a supplier of results, providing a single value of type T.
T get()
Function
Represents a function that accepts one argument of type T and produces a result of type R.
R apply(T t)
Predicate
Represents a predicate (boolean-valued function) of one argument.
boolean test(T t)
UnaryOperator
Represents an operation on a single operand of type T that produces a result of type T. Inherits from Function<T, T>.
T apply(T t)
BinaryOperator
Represents an operation upon two operands of the same type, producing a result of the same type as the operands.
T apply(T t1, T t2)
BiFunction
Represents a function that accepts two arguments of types T and U and produces a result of type R.
R apply(T t, U u)
BiPredicate
Represents a predicate (boolean-valued function) of two arguments.
boolean test(T t, U u)
BiConsumer
Represents an operation that accepts two input arguments of types T and U and returns no result.
We can implement the Application functional interface using an anonymous class.
AnonymousImpl.java
1 2 3 4 5 6 7 8 910111213141516
packagecom.java.core.functionalinterface;publicclassAnonymousImpl{publicStringexecute(){Applicationapplication=newApplication(){@OverridepublicStringgetApplicationId(StringappNumber){return"This is appId: "+appNumber;}};return"AnonymousImpl: "+application.getApplicationId("12345");}}
Next we can also use lambda expression to implement the Application functional interface.
LambdaExpressionImpl.java
1 2 3 4 5 6 7 8 910
packagecom.java.core.functionalinterface;publicclassLambdaExpressionImpl{publicStringexecute(){Applicationapplication=(appNumber->"This is appId: "+appNumber);return"LambdaExpressionImpl: "+application.getApplicationId("56789");}}
Next we can also use method referenced to implement the Application functional interface.
MethodReferenceImpl.java
1 2 3 4 5 6 7 8 91011121314
packagecom.java.core.functionalinterface;publicclassMethodReferenceImpl{publicStringexecute(){Applicationapplication=MethodReferenceImpl::getApplicationId;return"MethodReferenceImpl: "+application.getApplicationId("10111213");}publicstaticStringgetApplicationId(StringappNumber){return"This is appId: "+appNumber;}}
Next we can also use Class implementation to implement the Application functional interface.
ApplicationImpl.java
1 2 3 4 5 6 7 8 910
packagecom.java.core.functionalinterface;publicclassApplicationImplimplementsApplication{@OverridepublicStringgetApplicationId(StringappNumber){return"This is appId: "+appNumber;}}
AnonymousImpl: This is appId: 12345
LambdaExpressionImpl: This is appId: 56789
MethodReferenceImpl: This is appId: 10111213
ClassImpl: This is appId: 15161718