Skip to content
  • Functional Interfaces · Java

Functional Interfaces

LearnViaNotes @learnvianotes· 3 min read

An interface with exactly one abstract method — the target type that every lambda and method reference is converted to.

Declaring one

Java
public class Main {
    @FunctionalInterface
    interface Calculator {
        int apply(int a, int b);                 // the single abstract method

        default Calculator twice() {             // defaults are allowed
            return (a, b) -> apply(apply(a, b), b);
        }
    }

    public static void main(String[] args) {
        Calculator add = (a, b) -> a + b;
        Calculator mul = (a, b) -> a * b;
        System.out.println(add.apply(3, 4));
        System.out.println(mul.apply(3, 4));
        System.out.println(add.twice().apply(3, 4));   // (3 + 4) + 4
    }
}
Output
7
12
11
Java
@FunctionalInterface
interface Broken {
    void first();
    void second();      // error: Broken is not a functional interface
}

The java.util.function toolbox

You rarely need to declare your own — the JDK ships 43 standard shapes. Learn the six core ones; the rest are variations.

InterfaceMethodShapeTypical use
Predicate<T>boolean test(T t)T → booleanfilter, removeIf
Function<T, R>R apply(T t)T → Rmap, computeIfAbsent
Consumer<T>void accept(T t)T → nothingforEach
Supplier<T>T get()nothing → Tlazy defaults, orElseGet, factories
UnaryOperator<T>T apply(T t)T → TreplaceAll, Stream.iterate
BinaryOperator<T>T apply(T a, T b)(T, T) → Treduce, merge
BiFunction<T, U, R>R apply(T t, U u)(T, U) → RMap.compute, replaceAll on maps
BiConsumer<T, U> / BiPredicate<T, U>accept / testtwo inputsMap.forEach

Primitive specializations avoid boxing: IntPredicate, IntFunction<R>, ToIntFunction<T>, IntUnaryOperator, IntBinaryOperator, IntSupplier, IntConsumer (plus Long* / Double* versions, and ObjIntConsumer<T>).

Java
import java.util.function.*;

public class Main {
    public static void main(String[] args) {
        Predicate<String> isEmpty = String::isEmpty;
        Function<String, Integer> length = String::length;
        Consumer<String> shout = s -> System.out.println(s.toUpperCase());
        Supplier<String> greeting = () -> "hello";
        UnaryOperator<Integer> square = x -> x * x;
        BinaryOperator<Integer> max = Math::max;
        IntBinaryOperator add = (a, b) -> a + b;      // no boxing

        System.out.println(isEmpty.test(""));
        System.out.println(length.apply("lambda"));
        shout.accept("java");
        System.out.println(greeting.get());
        System.out.println(square.apply(7) + " " + max.apply(3, 9) + " " + add.applyAsInt(2, 3));
    }
}
Output
true
6
JAVA
hello
49 9 5

Composition

The standard interfaces have default methods that build new functions out of old ones — no new classes needed.

MethodOnMeaning
f.andThen(g)Function, Consumerrun f, then g on the result: g(f(x))
f.compose(g)Functionrun g first: f(g(x))
p.and(q) / p.or(q) / p.negate()Predicatelogical combination (short-circuits)
Predicate.not(p)Predicate (static, 11+)negate a method ref: filter(not(String::isBlank))
Function.identity()Function (static)x -> x
Java
import java.util.function.*;

public class Main {
    public static void main(String[] args) {
        Function<Integer, Integer> plus2 = x -> x + 2;
        Function<Integer, Integer> times3 = x -> x * 3;
        System.out.println(plus2.andThen(times3).apply(1));   // (1 + 2) * 3
        System.out.println(plus2.compose(times3).apply(1));   // (1 * 3) + 2

        Predicate<String> longWord = s -> s.length() > 4;
        Predicate<String> startsJ = s -> s.startsWith("J");
        System.out.println(longWord.and(startsJ).test("Java"));
        System.out.println(longWord.or(startsJ).test("Java"));
        System.out.println(longWord.negate().test("Java"));
    }
}
Output
9
5
false
true
true

What makes an interface functional?

Why do primitive specializations like IntPredicate exist?

Function vs UnaryOperator vs BinaryOperator?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report