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.

shadow-left