Functional Interfaces in Java
What Are Functional Interfaces?
Functional interfaces were introduced in Java 8. A functional interface is an interface with a single abstract method. They are also called Single Abstract Method Interfaces, or SAM Interfaces for short. They are used to provide the method signature for a lambda expression. When providing a parameter or a variable that is a lambda, the type you provide is a functional interface.
Creating and Using Functional Interfaces
Functional interfaces are just interfaces, so writing them isn't any different than a normal interface.
public interface MyInterface {
void print(final String value);
}
If you wanted to provide this as a method parameter, it would look like the following:
public void method(final MyInterface function) {
}
To invoke the lambda expression, you execute the abstract method in the functional interface.
public void method(final MyInterface function) {
function.print("Hello World");
}
@FunctionalInterface Annotation
Functional interfaces should be annotated using the @FuntionalInterface annotation. This allows you to get help from the compiler to ensure it is a functional interface.
@FunctionalInterface
public interface MyFunction {
String method(final String parameter);
}
Using the @FunctionalInterface annotation, if the interface contains more than one abstract method, it will generate a compiler error.
Default Methods in Functional Interfaces
Functional interfaces support the use of default methods. Since a default method has an implementation, it isn't an abstract method. You must have a single abstract method but can have zero or more default methods.
The java.util.function Package
The java.util.function package contains several functional interfaces. This is where you should start before creating custom functional interfaces. It covers most of the common functional interfaces needed with lambda expressions. The three most commonly used ones are the following:
Consumer
The Consumer interface contains the method accept() that takes a single generic parameter and returns void.
public void method(final Consumer<String> consumer) {
consumer.accept("Hello");
}
method(
parameter -> System.out.println(parameter);
);
Supplier
The Supplier interface contains the method get() that takes zero parameters and returns a generic value.
public void method(final Supplier<Integer> supplier) {
System.out.println(supplier.get());
}
final int result = method(
() -> 10
);
Function
The Function interface contains the method apply() that takes a generic parameter and returns a generic value. There are two generics defined on this interface. The first is the parameter type, and the second is the return type.
public void method(final Function<String, String> function) {
final String result = function.apply("Hello");
}
final String result = method(
parameter -> {
System.out.println(parameter);
return "Success";
}
);
Conclusion
Functional interfaces are single abstract method interfaces used for lambda expressions. When you need a functional interface, start with the java.util.function package before you create your own custom functional interface. When creating custom functional interfaces, always use @FunctionalInterface so the compiler can ensure that it is a single abstract method interface.