Functional interfaces
Match a lambda to the right java.util.function type instead of inventing your own.
Open this lesson in the learning hubKey points
- A functional interface has exactly one abstract method, which is what lets a lambda stand in for it.
Predicateanswers a question,Functiontransforms,Supplierproduces,Consumeraccepts.UnaryOperator<T>is a Function with the same input and output type;BiFunctiontakes two arguments.- They compose:
andThen,negate,andandorbuild a bigger one from small pieces. - In hot code prefer
IntPredicatetoPredicate<Integer>— the generic form boxes every value. @FunctionalInterfaceis optional, but it turns "someone added a second method" into a compile error.
Example
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
public class Main {
@FunctionalInterface
interface Discount { // your own: exactly one abstract method
double apply(double amount);
}
static double checkout(double amount, Discount d) { return d.apply(amount); }
public static void main(String[] args) {
Predicate<String> blank = s -> s.isBlank();
Function<String, Integer> length = String::length;
Supplier<List<String>> maker = ArrayList::new;
Consumer<String> printer = s -> System.out.println(" Consumer got: " + s);
BiFunction<Integer, Integer, Integer> add = (a, b) -> a + b;
UnaryOperator<String> shout = s -> s.toUpperCase() + "!";
System.out.println("Predicate : blank on two spaces = " + blank.test(" "));
System.out.println("Function : length of java = " + length.apply("java"));
System.out.println("Supplier : maker.get() = " + maker.get());
printer.accept("a value");
System.out.println("BiFunction : add(2, 3) = " + add.apply(2, 3));
System.out.println("UnaryOp : shout(hi) = " + shout.apply("hi"));
System.out.println("andThen : " + length.andThen(n -> n * 2).apply("java"));
System.out.println("negate : " + blank.negate().test(" "));
System.out.println("and : " + blank.negate().and(s -> s.length() > 2).test("java"));
System.out.println("your own interface: " + checkout(100, amount -> amount * 0.9));
System.out.println("a lambda only fits an interface with exactly one abstract method");
}
}
Learn the six shapes and you almost never declare an interface yourself.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Core Java course, and every lesson in it is listed on the Core Java contents page.