ZetCode

Java Supplier

last modified March 5, 2024

In this article we show how to work with the Supplier functional interface in Java.

Supplier

Java Supplier is a functional interface which represents an operation that returns a result. Supplier does not take any arguments.

@FunctionalInterface
public interface Supplier<T> {

    T get();
}

T is the type of results supplied by the supplier.

Supplier offers a concise and convenient way to represent value-providing functions, promoting lazy evaluation, code clarity, and compatibility with functional programming concepts in Java.

Simple Supplier example

The following example creates a simple supplier.

Main.java
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

void main() {

    var words = List.of("falcon", "cup", "fun", "cloud");

    var res = upperWords(words);
    System.out.println(res);
}

List<String> upperWords(List<String> words) {

    var uppered = new ArrayList<String>();

    for (var word : words) {

        Supplier<String> upperSupplier = word::toUpperCase;
        uppered.add(upperSupplier.get());
    }

    return uppered;
}

The program turns words into uppercase using upperSupplier.

Supplier<String> upperSupplier = word::toUpperCase;

The Supplier returns a string. It references the toUpperCase method of the String type.

$ java Main.java
[FALCON, CUP, FUN, CLOUD]

Product supplier

The next example creates a function that returns products.

Main.java
import java.util.function.Supplier;
import java.util.List;

Supplier<List<Product>> productSupplier = () -> {

    return List.of(
        new Product(1, "Product A"),
        new Product(2, "Product B"),
        new Product(3, "Product C"),
        new Product(4, "Product D"),
        new Product(5, "Product E"));
};

void main() {

    productSupplier.get().stream().limit(3).forEach(System.out::println);
}

record Product(int id, String name) {
}

The defined supplier returns a list of products.

productSupplier.get().stream().limit(3).forEach(System.out::println);

We retrieve the list with get. We transform it into a stream and fetch the first three products from the list.

$ java Main.java
Product[id=1, name=Product A]
Product[id=2, name=Product B]
Product[id=3, name=Product C]

IntSupplier

IntSupplier represents a supplier of int-valued results. This is the int-producing primitive specialization of Supplier.

Main.java
import java.util.stream.IntStream;
import java.util.function.IntSupplier;
import java.util.Random;

void main() {

    IntSupplier randIntSupp = () -> new Random().nextInt(40);

    System.out.println(randIntSupp.getAsInt());
    System.out.println(randIntSupp.getAsInt());

    System.out.println("--------------------");

    IntStream.generate(randIntSupp).limit(6).forEach(System.out::println);
}

The program creates a supplier of random integers.

IntSupplier randIntSupp = () -> new Random().nextInt(40);

The IntSupplier returns a random integer in range [0,40).

System.out.println(randIntSupp.getAsInt());

We get a random integer with getAsInt.

IntStream.generate(randIntSupp).limit(6).forEach(System.out::println);

A stream of six random integers is generated.

$ java Main.java
4
35
--------------------
31
4
10
30
15
8

Supplier of fibonacci values

The next example creates a supplier which generates a sequence of fibonacci values.

Main.java
import java.util.function.Supplier;
import java.util.stream.Stream;

Supplier<Long> fibonacciSupplier = new Supplier<Long>() {

    long a = 0, b = 1;

    public Long get() {

        long nextValue = a + b;
        a = b;
        b = nextValue;
        return a;
    }
};

void main() {

    Stream<Long> fibs = Stream.generate(fibonacciSupplier);
    fibs.limit(20).forEach(e -> System.out.print(STR."\{e} "));
}

We create a stream from the fibonacci supplier and fetch first twenty values.

$ java Main.java
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 

CompletableFuture.supplyAsync

The Supplier interface is used in various Java APIs. For instance, the CompletableFuture.supplyAsync returns a CompletableFuture that is asynchronously completed.

Main.java
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

void main() throws ExecutionException, InterruptedException {

    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return new Random().nextInt(40);
    });

    System.out.println(future.get());
}

The program returns a random integer in range [0,40) in an async operation.

In this article we have worked with Java Supplier interface.

CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (InterruptedException e) {
        throw new IllegalStateException(e);
    }
    return new Random().nextInt(40);
});

CompletableFuture takes a Supplier as a parameter.

Source

Java Supplier - language reference

In this article we have worked with the Supplier Java interface.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Java tutorials.