Functional Programming & Streams
Standard Functional Interfaces
java.util.function supplies the vocabulary of functional Java: Function, Predicate, Consumer, Supplier, the two-arg Bi* forms, operators, and primitive specializations. Use these instead of inventing your own (EJ 44).- Six core shapes:
Function<T,R>,Predicate<T>,Consumer<T>,Supplier<T>,UnaryOperator<T>,BinaryOperator<T> - Primitive specializations (
IntPredicate,LongFunction…) avoid boxing — prefer them - Composition:
f.andThen(g),f.compose(g),p.and(q).or(r),p.negate() - Write your own only with a compelling reason — then annotate
@FunctionalInterface Comparatoris the star example of a custom functional interface that earns its keep
| Interface | Signature | Typical use |
|---|---|---|
Function<T,R> | R apply(T t) | transform a value — map |
Predicate<T> | boolean test(T t) | filter, match |
Consumer<T> | void accept(T t) | side effects — forEach |
Supplier<T> | T get() | lazy creation, factories |
UnaryOperator<T> | T apply(T t) | same-type transform — replaceAll |
BinaryOperator<T> | T apply(T a, T b) | combine — reduce, merge |
Predicate<String> nonBlank = s -> !s.isBlank();
Predicate<String> shortEnough = s -> s.length() <= 80;
Predicate<String> valid = nonBlank.and(shortEnough);
Function<String, String> clean = String::strip;
Function<String, String> normalize = clean.andThen(String::toLowerCase);