In Java we can use the generate
method of the Stream
class to create an infinite stream of values. The values are coming from a Supplier
instance we pass as argument to the generate
method. The Supplier
instance usually will be a lambda expression. To give back a fixed value we simply implement a Supplier
that returns the value. We can also have different values when we use a method that returns a different value on each invocation, for example the randomUUID
method of the UUID
class. When we use such a method we can create the Supplier
as method reference: UUID::randomUUID
.
The generate
method returns an unbounded stream. We must use methods like limit
and takeWhile
to get a bounded stream again. We must use findFirst
or findAny
to terminate the unbounded stream and get a value.
In the following example we use the generate
method with a Supplier
that returns a repeating fixed String
value and some different values from invoking the now
method of LocalTime
:
package mrhaki.stream; import java.time.LocalTime; import java.util.List; import java.util.stream.Stream; import static java.util.stream.Collectors.toUnmodifiableList; public class Generate { public static void main(String[] args) { // Create a infinite stream where each item is the string value "Java". // We let the supplier function return a fixed value "Java". assert Stream.generate(() -> "Java") .limit(4) .collect(toUnmodifiableList()).equals(List.of("Java", "Java", "Java", "Java")); // Create an infinite stream of function invocations of LocalTime.now(). // The supplier function returns a different value for each invocation. var currentTimes = Stream.generate(LocalTime::now) .limit(2) .collect(toUnmodifiableList()); assert currentTimes.get(0).isBefore(currentTimes.get(1)); // Create a list of 100 time values where each value should be later than the next. var timeSeries = Stream.generate(LocalTime::now).limit(100).collect(toUnmodifiableList()); assert latestTime(timeSeries).equals(timeSeries.get(timeSeries.size() - 1)); } /** * Get the latest time from a serie of time values. * * @param times List with time values. * @return Latest time value from the collection. */ private static LocalTime latestTime(List<LocalTime> times) { return times.stream().reduce((acc, time) -> { if (acc.isAfter(time)) { return acc; } else { return time; } }).get(); } }
Written with Java 14.