13.5 Suppliers
As the name suggests, the Supplier<T> functional interface represents a supplier of values. From Table 13.4, we see that its functional method get() has the type () -> T—that is, it takes no argument and returns a value of type T.
Table 13.4 shows all supplier functional interfaces provided in the java.util.function package. Apart from the functional method shown in Table 13.4, these functional interfaces do not define any additional methods.
Table 13.4 Suppliers
Functional interface (T, U, and R are type parameters) | Functional method | Default methods |
Supplier<T> | get: () -> T | – |
IntSupplier | getAsInt: () -> int | – |
LongSupplier | getAsLong: () -> long | – |
DoubleSupplier | getAsDouble: () -> double | – |
BooleanSupplier | getAsBoolean: () -> boolean | – |
A supplier typically generates, creates, or produces values. Example 13.4 illustrates defining and using suppliers.
The supplier at (1) in Example 13.4 will always create a StringBuilder from the string “Howdy”. The StringBuilder is not created until the get() method of the supplier is called.
Supplier<StringBuilder> createSB = () -> new StringBuilder(“Howdy!”); // (1)
System.out.println(createSB.get()); // Prints: Howdy!
String str = “uppercase me!”;
Supplier<String> makeUppercase = () -> str.toUpperCase(); // (2)
System.out.println(makeUppercase.get()); // Prints: UPPERCASE ME!
The supplier at (2) returns a string that is an uppercase version of the string on which the method toUppercase() is invoked. Note that the value of the reference str is captured at (2) when the lambda expression is defined and the reference str is effectively final. Calling the get() method of the supplier results in the toUppercase() method being invoked on the String instance referenced by the reference str.
In the examples below, we use a pseudorandom number generator to define a supplier that can return integers between different ranges. The intSupplier below generates a number between 0 (inclusive) and 100 (exclusive).
Random numGen = new Random();
Supplier<Integer> intSupplier = () -> numGen.nextInt(100); // numGen effect. final
System.out.println(intSupplier.get()); // Prints a number in [0, 100).
The generic method listBuilder() at (12) can be used to build a list of specified length, where the specified supplier generates a value every time the get() method is called at (13).
The code below builds a list of Integer with five values between 0 (inclusive) and 100 (exclusive) by calling the listBuilder() method.
List<Integer> intRefList = listBuilder(5, () -> numGen.nextInt(100));