Java's functional interfaces fall into four primary categories. Memorizing these patterns helps when working with lambda expressions and the Streams API.
Consumer Interfaces
A Consumer accepts a parameter but produces no return value.
@FunctionalInterface
public interface Consumer<T> {
void accept(T input);
default Consumer<T> andThen(Consumer<? super T> next) {
Objects.requireNonNull(next);
return (T t) -> { accept(t); next.accept(t); };
}
}
Variants:
| Interface | Description |
|---|---|
| BiConsumer<T, U> | Accepts two parameters |
| DoubleConsumer | Accepts a primitive double |
| IntConsumer | Accepts a primitive int |
| LongConsumer | Accepts a primitive long |
| ObjDoubleConsumer<T> | First parameter is T, second is double |
| ObjIntConsumer<T> | First parameter is T, second is int |
| ObjLongConsumer<T> | First parameter is T, second is long |
Supplier Interfaces
A Supplier takes no parameters but returns a value.
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Variants:
| Interface | Return Type |
|---|---|
| BooleanSupplier | boolean |
| DoubleSupplier | double |
| IntSupplier | int |
| LongSupplier | long |
Predicate Interfaces
A Predicate evaluates a condition and returns a boolean result.
@FunctionalInterface
public interface Predicate<T> {
boolean test(T input);
}
Variants:
| Interface | Parameters |
|---|---|
| BiPredicate<T, U> | Two parameters |
| DoublePredicate | One double parameter |
| IntPredicate | One int parameter |
| LongPredicate | One long parameter |
Function Interfaces
A Function accepts one parameter and produces a result. This category sees the most practical use.
@FunctionalInterface
public interface Function<T, R> {
R apply(T input);
}
Varients:
Unary Operators (input and output share the same type):
- UnaryOperator<T> extends Function<T, T>
- IntUnaryOperator
- LongUnaryOperator
- DoubleUnaryOperator
Multi-paramter functions:
- BiFunction<T, U, R> — two inputs, one output
- DoubleFunction<R> — double input, generic output
- IntFunction<R> — int input, ganeric output
- LongFunction<R> — long input, generic output
Type conversion functions:
- IntToDoubleFunction
- IntToLongFunction
- DoubleToIntFunction
- DoubleToLongFunction
- LongToIntFunction
- LongToDoubleFunction
Special case:
- BinaryOperator<T> — accepts two parameters of the same type and returns the same type, making it essentially a BiFunction<T, T, T>
These four categories form the foundation for most lambda expressions and method references encountered in modern Java development.