The behavior of the Stream.generate method when passing a provider argument <Stream <T>>
After reading this question and one of my answers, I decided to independently perform some tests. To my surprise, I came to a situation that looks rather strange.
Here is the code:
public class InfiniteRepeatingStream {
public static void main(String[] args) {
Stream<Integer> s1 = repeatFromSupplier(() -> Stream.of(1, 2, 3));
s1.sequential().limit(10).forEachOrdered(System.out::print);
System.out.print("\n----------------\n");
Stream<Integer> s2 = repeatFromStream(Stream.of(1, 2, 3));
s2.sequential().limit(10).forEachOrdered(System.out::print);
}
static <T> Stream<T> repeatFromSupplier(Supplier<Stream<T>> supplier) {
return Stream.generate(supplier).flatMap(s -> s);
}
static <T> Stream<T> repeatFromStream(Stream<T> stream) {
return Stream.generate(() -> stream).flatMap(s -> s);
}
}
As you can see, the difference between the methods repeatFromSupplier
and repeatFromStream
is lying on his argument and that is passed to the method Stream.generate
.
While the method repeatFromSupplier
receives the type argument Supplier<Stream<T>>
and passes this argument directly to the method Stream.generate
, the method repeatFromStream
receives the type argument Stream<T>
and creates an Supplier<Stream<T>>
expression from the built-in lambda () -> stream
that is immediately passed to the method Stream.generate
.
, , , .
repeatFromSupplier
repeatFromStream
. , , repeatFromSupplier
( 1231231231
), repeatFromStream
123
IllegalStateException: stream has already been operated upon or closed
.
, . . , -.