2 min read

Functional Interfaces in Java

Functional interfaces are single abstract method interfaces used for lambda expressions.
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.