看完this question和 one of its answers ,我决定自己进行一些测试。令我惊讶的是,我遇到了一个看起来很奇怪的情况。
代码如下:
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);
}
}
如您所见,repeatFromSupplier
之间的区别和 repeatFromStream
方法取决于它的参数以及传递给 Stream.generate
的内容方法。
虽然repeatFromSupplier
方法接收类型为 Supplier<Stream<T>>
的参数并将此参数直接传递给 Stream.generate
方法,repeatFromStream
方法接收类型为 Stream<T>
的参数并创建一个 Supplier<Stream<T>>
通过 () -> stream
内联 lambda 表达式,立即传递给 Stream.generate
方法。
我希望这两种方法表现出相同的行为,因为我认为差异只是表面上的。
但是,此代码显示了 repeatFromSupplier
的不同行为和 repeatFromStream
方法。如果你运行它,你会注意到 repeatFromSupplier
方法按预期工作(它打印 1231231231
),而 repeatFromStream
方法打印 123
并抛出 IllegalStateException: stream has already been operated upon or closed
.
现在,我确实知道抛出此异常的原因和时间。我不是在问这个。相反,我想知道为什么这两种方法的行为不同。
最佳答案
在 s1
的标称情况下,您每次都调用供应商创建一个新流:
() -> Stream.of(1, 2, 3)
但在 s2
的情况下,您创建了一个流,然后始终从供应商返回相同的实例:
() -> stream
这与这段代码本质上是一样的:
Stream<Integer> s = Stream.of(1, 2, 3); // now Stream.of is only executed once
Stream<Integer> s1 = repeatFromSupplier(() -> s);
s1.sequential().limit(10).forEachOrdered(System.out::print);
这也会引发异常。
关于java - 传递 Supplier<Stream<T>> 参数时 Stream.generate 方法的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48120779/