Skip to content

Java 8 Functional Interface#

Definition#

  • 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
1
2
3
4
5
6
7
// functional interface without anotation

public interface Application {

public String getApplicationId(String appNumber);

}
Application.java
1
2
3
4
5
6
7
8
// functional interface with anotation

@FunctionalInterface
public interface Application {

public String getApplicationId(String appNumber);

}
  • 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. void accept(T t, U u)

Implementation#

  • There are 4 ways to implement the functional interface.
  • For example we have a functional interface as below.
Application.java
1
2
3
4
5
6
7
package com.java.core.functionalinterface;  

@FunctionalInterface  
public interface Application {  
String getApplicationId(String appNumber);  

}

Anonymous Inner Class#

  • We can implement the Application functional interface using an anonymous class.
AnonymousImpl.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package com.java.core.functionalinterface;


public class AnonymousImpl {

    public String execute() {
        Application application = new Application() {
            @Override
            public String getApplicationId(String appNumber) {
                return "This is appId: " + appNumber;
            }
        };
        return "AnonymousImpl: " + application.getApplicationId("12345");
    }

}
  • Then we can use it like this below.
Java8FunctionalInterface.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.java.core.functionalinterface;

public class Java8FunctionalInterface {

    public static void main(String[] args) {
        AnonymousImpl anonymous = new AnonymousImpl();
        System.out.println(anonymous.execute());
    }

}
AnonymousImpl: This is appId: 12345

Lambda Expression#

  • Next we can also use lambda expression to implement the Application functional interface.
LambdaExpressionImpl.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.java.core.functionalinterface;

public class LambdaExpressionImpl {

    public String execute() {
        Application application = (appNumber -> "This is appId: " + appNumber);
        return "LambdaExpressionImpl: " + application.getApplicationId("56789");
    }

}
  • Then we can use it like this below.
Java8FunctionalInterface.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package com.java.core.functionalinterface;

public class Java8FunctionalInterface {

    public static void main(String[] args) {
        AnonymousImpl anonymous = new AnonymousImpl();
        System.out.println(anonymous.execute());

         LambdaExpressionImpl lambdaExpression = new LambdaExpressionImpl();
        System.out.println(lambdaExpression.execute());
    }

}
AnonymousImpl: This is appId: 12345
LambdaExpressionImpl: This is appId: 56789

Method Referenced#

  • Next we can also use method referenced to implement the Application functional interface.
MethodReferenceImpl.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package com.java.core.functionalinterface;

public class MethodReferenceImpl {

    public String execute() {
        Application application = MethodReferenceImpl::getApplicationId;
        return "MethodReferenceImpl: " + application.getApplicationId("10111213");
    }

    public static String getApplicationId(String appNumber) {
        return "This is appId: " + appNumber;
    }

}
  • Then we can use it like this below.
Java8FunctionalInterface.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
package com.java.core.functionalinterface;

public class Java8FunctionalInterface {

    public static void main(String[] args) {
        AnonymousImpl anonymous = new AnonymousImpl();
        System.out.println(anonymous.execute());

         LambdaExpressionImpl lambdaExpression = new LambdaExpressionImpl();
        System.out.println(lambdaExpression.execute());

        MethodReferenceImpl methodReference = new MethodReferenceImpl();
        System.out.println(methodReference.execute());
    }

}
AnonymousImpl: This is appId: 12345
LambdaExpressionImpl: This is appId: 56789
MethodReferenceImpl: This is appId: 10111213

Class Implementation#

  • Next we can also use Class implementation to implement the Application functional interface.
ApplicationImpl.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.java.core.functionalinterface;

public class ApplicationImpl implements Application {

    @Override
    public String getApplicationId(String appNumber) {
        return "This is appId: " + appNumber;
    }

}
ClassImpl.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package com.java.core.functionalinterface;

public class ClassImpl {

    public String execute() {
        Application application = new ApplicationImpl();
        return "ClassImpl: " + application.getApplicationId("15161718");
    }

}
  • Then we can use it like this below.
Java8FunctionalInterface.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
package com.java.core.functionalinterface;

public class Java8FunctionalInterface {

    public static void main(String[] args) {
        AnonymousImpl anonymous = new AnonymousImpl();
        System.out.println(anonymous.execute());

         LambdaExpressionImpl lambdaExpression = new LambdaExpressionImpl();
        System.out.println(lambdaExpression.execute());

        MethodReferenceImpl methodReference = new MethodReferenceImpl();
        System.out.println(methodReference.execute());

        ClassImpl classImpl = new ClassImpl();
        System.out.println(classImpl.execute());
    }

}
AnonymousImpl: This is appId: 12345
LambdaExpressionImpl: This is appId: 56789
MethodReferenceImpl: This is appId: 10111213
ClassImpl: This is appId: 15161718

See Also#

References#