Fundamentals 23 min read

Master Java Supplier and Consumer Interfaces with Practical Examples

This article explains Java 8's Supplier and Consumer functional interfaces, illustrates their definitions, shows real‑world use cases such as random number generation, object creation, stream data sources, printing and validation, compares them with anonymous classes and lambdas, and connects them to design patterns and parameterized method calls.

Ubiquitous Tech
Ubiquitous Tech
Ubiquitous Tech
Master Java Supplier and Consumer Interfaces with Practical Examples

Background

Java 8 introduced functional interfaces, among which Supplier and Consumer are fundamental building blocks for providing data and processing data.

Supplier Interface

Supplier<T>

has a single abstract method T get() that takes no arguments and returns a result of type T.

package java.util.function;
/**
 * Represents a supplier of results.
 * @param <T> the type of results supplied by this supplier
 */
@FunctionalInterface
public interface Supplier<T> {
    /** Gets a result. */
    T get();
}

Typical scenarios:

Random number generation:

Supplier<Integer> randomNumberSupplier = () -> new Random().nextInt(100);
System.out.println(randomNumberSupplier.get());

Object creation:

Supplier<User> userSupplier = () -> new User("张三", 25);
User user = userSupplier.get();
System.out.println(user);

Stream data source:

Supplier<Integer> numberSupplier = () -> (int) (Math.random() * 100);
Stream<Integer> numberStream = Stream.generate(numberSupplier);
numberStream.limit(5).forEach(System.out::println);

Consumer Interface

Consumer<T>

defines a single abstract method void accept(T t) that consumes a value without returning a result.

/**
 * Represents an operation that accepts a single input argument and returns no result.
 */
@FunctionalInterface
public interface Consumer<T> {
    /** Performs this operation on the given argument. */
    void accept(T t);
}

Typical scenarios:

Printing data:

Consumer<String> printConsumer = System.out::println;
printConsumer.accept("Hello, World!");

Data validation:

Consumer<String> validationConsumer = s -> {
    if (s.length() < 5) {
        throw new IllegalArgumentException("数据长度不足");
    }
    // other validation logic
};
validationConsumer.accept("12345");

Modifying collection elements:

Consumer<Integer> multiplyByTwo = n -> n *= 2;
numbers.forEach(multiplyByTwo);

Anonymous Classes vs. Lambdas

Using an anonymous inner class to implement Supplier and Consumer requires boilerplate code, while a lambda expression provides a concise alternative:

// Anonymous class
Supplier<Integer> numberSupplier = new Supplier<Integer>() {
    @Override public Integer get() { return 42; }
};
Consumer<Integer> numberConsumer = new Consumer<Integer>() {
    @Override public void accept(Integer v) { System.out.println("The number is: " + v); }
};
// Lambda version
Supplier<Integer> numberSupplier = () -> 42;
Consumer<Integer> numberConsumer = v -> System.out.println("The number is: " + v);

Parameterized Passing

Methods can accept Supplier or Consumer as parameters, enabling flexible data flow:

public static void methodOne() {
    Supplier<String> dataSupplier = () -> "Data provided by Supplier";
    methodTwo(dataSupplier);
}
public static void methodTwo(Supplier<String> supplier) {
    System.out.println("Data obtained from Supplier: " + supplier.get());
}
public static void methodOne() {
    Consumer<String> operationConsumer = msg -> System.out.println("Executing operation on message: " + msg);
    methodTwo("Hello, World!", operationConsumer);
}
public static void methodTwo(String msg, Consumer<String> consumer) {
    System.out.println("Processing message: " + msg);
    consumer.accept(msg);
}

Design‑Pattern Connections

Strategy pattern can use Supplier to supply a strategy implementation:

public static void executeStrategy(Supplier<String> strategy) {
    System.out.println("Strategy result: " + strategy.get());
}
Supplier<String> s1 = () -> "Strategy One Executed";
Supplier<String> s2 = () -> "Strategy Two Executed";
executeStrategy(s1);
executeStrategy(s2);

Consumer pattern processes each element of a collection:

public static void processData(List<String> data, Consumer<String> consumer) {
    data.forEach(consumer::accept);
}
Consumer<String> printer = System.out::println;
processData(Arrays.asList("A", "B", "C"), printer);

Adapter pattern can wrap a legacy API with a Supplier:

class Adapter implements Supplier<String> {
    private final OldApi oldApi;
    Adapter(OldApi oldApi) { this.oldApi = oldApi; }
    @Override public String get() { return oldApi.getData(); }
}
Supplier<String> adapter = new Adapter(new OldApi());
System.out.println(adapter.get());

Comparison

Supplier

provides a value (no input, returns a result); Consumer consumes a value (takes one input, returns void). Use Supplier for lazy or deferred computation, and Consumer for side‑effect operations such as printing or modifying collections.

Learning Tips

Understand the core concepts, write small examples, apply them in real projects, create personal scenarios, study open‑source code, and regularly review.

Real‑World Usage

Many libraries already use these interfaces. For example, Spring’s RequestFactoryCustomizer implements Consumer<ClientHttpRequestFactory> to customize request factories.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaLambdaconsumerFunctional InterfaceSupplier
Ubiquitous Tech
Written by

Ubiquitous Tech

A ubiquitous public account for pirate enthusiasts, regularly sharing curated experiences, tech learning, and growth insights. Currently publishing articles on AI RAG customer service, AI MCP technology, and open-source design. Personal free Knowledge Planet: Awakening New World Programmer.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.