Predicate, Consumer, Supplier, Function — The 4 Core Functional Interfaces
Fast recall
Quick revision
Core answer
Predicate: T → boolean (filter/test). Consumer: T → void (side effects). Supplier: () → T (lazy creation). Function: T → R (transform). Compose: Predicate with .and(), .or(), .negate(); Function with .andThen() (left-to-right) / .compose() (right-to-left). BiPredicate, BiConsumer, BiFunction for two-arg variants. Primitive specializations (IntPredicate, LongFunction) avoid boxing overhead.Whether the candidate understands the four core functional interfaces as building blocks for Stream operations and lambda expressions — not just their names but what problem each one solves
Confusing Function and Consumer — Function returns a value (transformation), Consumer doesn't (side effect). Not knowing that Predicate, Consumer, Supplier, and Function are in java.util.function and are used extensively by the Stream API
Show how these compose — Predicate.and(), Predicate.or(), Function.andThen(), Function.compose(). Mention specialized primitive variants (IntPredicate, LongFunction, ToIntFunction) that avoid autoboxing overhead in performance-sensitive code
Interview-ready guide
Interview answer
Four core functional interfaces power all Stream operations, each with a distinct signature.
The four interfaces
Predicate: T → boolean — used infilter(),anyMatch(),allMatch()Consumer: T → void — used inforEach(),peek(); side effects onlySupplier: () → T — used inorElseGet(),Stream.generate(); lazy production of valuesFunction: T → R — used inmap(); transformation from one type to another
Why they're powerful: composition
Predicate.and(),.or(),.negate()build complex filters from simple reusable piecesFunction.andThen()chains transformations left-to-right without intermediate variablesactiveFilter.and(premiumFilter)is clearer than nested boolean logic
Primitive variants — avoid autoboxing
IntPredicate,LongConsumer,ToIntFunctionwork with raw primitives- In a stream over millions of elements,
Predicateboxes every value;IntPredicateeliminates those allocations
I recommend learning the composition methods — .and(), .andThen(), .compose() — they let you build complex logic from simple reusable predicates and functions.
Predicate, Consumer, Supplier, Function — The 4 Core Functional Interfaces
Direct Answer
Predicate<T>: T → boolean (filter/test). Consumer<T>: T → void (side effects). Supplier<T>: () → T (lazy creation). Function<T,R>: T → R (transform). Compose: Predicate with .and(), .or(), .negate(); Function with .andThen() (left-to-right) / .compose() (right-to-left). BiPredicate, BiConsumer, BiFunction for two-arg variants. Primitive specializations (IntPredicate, LongFunction) avoid boxing overhead.
Common Mistakes & Pitfalls
Confusing Function and Consumer — Function returns a value (transformation), Consumer doesn't (side effect). Not knowing that Predicate, Consumer, Supplier, and Function are in java.util.function and are used extensively by the Stream API
Check your understanding
Answer these without looking back at the article.
- What is the difference between Function.andThen() and Function.compose() — which transformation applies first?
- When would you use a Supplier<T> instead of just computing and passing the value directly?
- How do you chain multiple Predicates and does short-circuit evaluation apply?
- Why do primitive specializations like IntPredicate and LongFunction exist alongside the generic versions?
- What is UnaryOperator<T> and BinaryOperator<T> — how do they relate to Function?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.