Supplier interface was introduced in java 8.
It belongs to java.util.function package and is a Functional interface with a single abstract method get().

get() takes no argument and returns a value and hence the name Supplier, which is capable of supplying a value.

If you look at the signature of get() method, it is

T get()

where T is the generic type.
Creating Supplier
Supplier is a functional interface and thus, it can be represented as a Lambda expression.
A simplest supplier example is one which returns a number(or String) as shown below.

Supplier<Integer> s = () -> 24;

This also means that where ever a Supplier is expected, a Lambda expression which expects no arguments and returns a value may be provided as shown below.

// method expecting a Supplier
public void print(Supplier<String> s){
   // more code
}

// invoke this method
print(() -> "Learning Supplier");

If you do not prefer to use a Lambda expression, then a Supplier may be created as an anonymous inner class as shown below.

Supplier<String> s = new Supplier<String>() {

   @Override
   public String get() {
      return "Learning Supplier";
   }
};

// method expecting a Supplier 
public void print(Supplier<String> s){
    // more code
} 

// invoke this method 
print(s);

Returning value: Supplier example
Once a Supplier is created, we can retrieve its value by invoking get() method as shown below in the example below.

Supplier<Integer> s = () -> 24;
System.out.println(s.get());   // prints 24

Supplier Example 2
Above example is pretty simple. A Supplier may also be used to generate a random number in a range as shown below.

// generates a random integer
Supplier<Integer> r = () -> new Random().nextInt(50);
System.out.println(r.get());

Supplier in the above example generates a random integer between 0 and 50(excluded) every time it is invoked.

Why Supplier
One might ask, Why should I use Supplier when a number can be generated or a String can be returned straight away.
Answer is, Using a supplier abstracts or separates out data generation from the code that uses it.

There are many methods in java api that utilize this concept and expect a Supplier object such as

1. generate() method in java.util.stream.Stream interface
generate() is a default interface method used for generating a stream of random numbers according to the Supplier provided to it.
This Supplier contains the logic to generate random numbers, thus it abstracts the random number generation from stream generation.

2. log() method in java.util.logging.Logger class
This method accepts a Supplier object in addition to a Log level. The Supplier is responsible to generating or supplying the message to be logged.
This separates the message generation from logging. Thus, you can generate log messages in a separate java thread if required.
This becomes extremely useful if the messages are being retrieved from a network call.

Hope the explanation was useful.

Leave a Reply