Java Functional Interfaces
In this page:
@FunctionalInterface
interface InterfaceName {
returnType methodName(parameters); // exactly one abstract method
}
InterfaceName variable = (parameters) -> expression;
What is a Functional Interface?
A functional interface is any interface that contains exactly one abstract method, making it a valid target for a lambda expression or method reference. You can (and should) annotate one with @FunctionalInterface, which tells the compiler to verify the interface truly has just one abstract method and fail the build otherwise.
Example: What is a Functional Interface?
// Define the class Main
public class Main {
@FunctionalInterface
// Define the interface Operation
interface Operation {
int apply(int a, int b);
}
// Program entry point: the JVM starts running here
public static void main(String[] args) {
Operation add = (a, b) -> a + b;
// Print a line to the console
System.out.println(add.apply(2, 3));
}
}
Login to try C/C++/Java/PHP code in the editor
The Predicate Interface
The Predicate interface is a built-in functional interface that accepts a single argument and returns a boolean, making it the standard shape for filtering conditions. It lives in the java.util.function package alongside Java's other general-purpose functional interfaces.
Example: The Predicate Interface
// Import java.util.function.Predicate so it can be used by its short name
import java.util.function.Predicate;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
Predicate<Integer> isEven = n -> n % 2 == 0;
// Print a line to the console
System.out.println(isEven.test(4));
// Print a line to the console
System.out.println(isEven.test(7));
}
}
Login to try C/C++/Java/PHP code in the editor
The Function Interface
The Function interface accepts a single argument of one type and returns a result of a potentially different type, representing a transformation from input to output. It's commonly used for data conversion or mapping operations, such as turning a String into an Integer.
Example: The Function Interface
// Import java.util.function.Function so it can be used by its short name
import java.util.function.Function;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
Function<String, Integer> toLength = s -> s.length();
// Print a line to the console
System.out.println(toLength.apply("hello"));
}
}
Login to try C/C++/Java/PHP code in the editor
Consumer and Supplier
The Consumer interface accepts a single argument and returns no result, representing an operation performed purely for its side effect, like printing a value. The Supplier interface is its mirror image: it accepts no arguments at all and simply produces a generated result on demand.
Example: Consumer and Supplier
// Import java.util.function.Consumer so it can be used by its short name
import java.util.function.Consumer;
// Import java.util.function.Supplier so it can be used by its short name
import java.util.function.Supplier;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
Consumer<String> printer = s -> System.out.println("Got: " + s);
Supplier<String> generator = () -> "generated value";
printer.accept(generator.get());
}
}
Login to try C/C++/Java/PHP code in the editor
BiFunctional Interfaces
Java also provides two-argument variants of these core interfaces for cases involving pairs of values: BiFunction accepts two arguments and returns a computed result, while BiConsumer accepts two arguments and performs a side effect without returning anything.
Example: BiFunctional Interfaces
// Import java.util.function.BiFunction so it can be used by its short name
import java.util.function.BiFunction;
// Import java.util.function.BiConsumer so it can be used by its short name
import java.util.function.BiConsumer;
// Define the class Main
public class Main {
// Program entry point: the JVM starts running here
public static void main(String[] args) {
BiFunction<Integer, Integer, Integer> multiply = (a, b) -> a * b;
BiConsumer<String, Integer> log = (name, age) -> System.out.println(name + " is " + age);
// Print a line to the console
System.out.println(multiply.apply(3, 4));
log.accept("Sam", 30);
}
}
Login to try C/C++/Java/PHP code in the editor
- Calling the wrong method name, such as
predicate.apply(x); the method istestfor Predicate,applyfor Function,acceptfor Consumer andgetfor Supplier. - Adding a second abstract method to an interface marked
@FunctionalInterface, which causes a compile error because it must have exactly one. - Expecting a Consumer to return a result, when it returns
void; use Function if you need a value back.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: