AddThis

Monday, 27 July 2026

Core functional interfaces in Java (Function, Predicate, Consumer, and Supplier)

 The four core functional interfaces in Java (Function, Predicate, Consumer, and Supplier) are the backbone of lambda expressions and the Stream API. They are differentiated entirely by what they take in (inputs) and what they give back (outputs).

Here is a visual summary of their structures:
Interface    Input Args    Returns    Primary MethodCommon Use Case
Function<T, R>    1 (T)        Value (R)  apply(T t)      Transforming data (e.g., map)
Predicate<T>    1 (T)    boolean  test(T t)      Filtering data (e.g., filter)
Consumer<T>    1 (T)    void  accept(T t)      Consuming data (e.g., forEach)
Supplier<T>    0        Value (T)  get()      Generating data (e.g., orElseGet)

1. Function<T, R> (The Transformer)
A Function takes exactly one input argument of type T, processes it, and returns a result of type R. Think of it as a machine that transforms raw material into a finished product. [1, 2]
  • Example: Converting a String into its length (Integer).
java
import java.util.function.Function;

// Takes a String, returns an Integer
Function<String, Integer> stringLength = str -> str.length();

// Usage
Integer length = stringLength.apply("Hello World"); 
System.out.println(length); // Outputs: 11
2. Predicate (The Filter)
A Predicate takes one input argument of type T and always returns a boolean (true or false). It evaluates whether the input matches a specific condition. [1, 2, 3, 4]
  • Example: Checking if a number is greater than 10.
java
import java.util.function.Predicate;

// Takes an Integer, returns true/false
Predicate<Integer> isGreaterThanTen = num -> num > 10;

// Usage
boolean result = isGreaterThanTen.test(5); 
System.out.println(result); // Outputs: false


3. Consumer (The End of the Line)

A Consumer takes one input argument of type T and returns nothing (void). It executes an action with the data (like printing, saving to a database, or logging) without modifying the data pipeline. [1, 2, 3, 4, 5]
  • Example: Printing a string in lowercase.
java
import java.util.function.Consumer;

// Takes a String, performs an action, returns void
Consumer<String> printLower = str -> System.out.println(str.toLowerCase());

// Usage
printLower.accept("JAVA"); // Outputs: java

4. Supplier (The Factory)
A Supplier takes no arguments but returns a value of type T. It acts as a data generator or a factory, often used for lazy evaluation (creating objects only when they are explicitly needed).
  • Example: Generating a random double value.
java
import java.util.function.Supplier;

// Takes no inputs, returns a Double
Supplier<Double> randomValue = () -> Math.random();

// Usage
Double val = randomValue.get(); 
System.out.println(val); // Outputs a random number (e.g., 0.6723)
All Four Working Together in a Single Pipeline
To see how they complement each other, look at how a standard Java Stream chain utilizes them in sequence:
java
import java.util.List;
import java.util.stream.Stream;

public class CombinedExample {
    public static void main(String[] args) {
        
        List<String> names = List.of("Alice", "Bob", "Charlie", "David");

        names.stream()
             .filter(name -> name.startsWith("C"))       // 1. Predicate: Filters elements
             .map(name -> name.toUpperCase())            // 2. Function: Transforms elements
             .forEach(name -> System.out.println(name)); // 3. Consumer: Processes final elements

        // 4. Supplier: Provides a fallback if no names matched the criteria
        String fallback = Stream.<String>empty()
                                .findFirst()
                                .orElseGet(() -> "Default Name"); 
    } 

Core functional interfaces in Java (Function, Predicate, Consumer, and Supplier)

  The four core functional interfaces in Java ( Function , Predicate , Consumer , and Supplier ) are the backbone of lambda expressions and ...