java - 传递 Supplier<Stream<T>> 参数时 Stream.generate 方法的行为

标签 java lambda parameters java-8 java-stream

看完this questionone 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/

相关文章:

java - 将 Kinesis Client Library (KCL) 日志转储到文件

java - 在android中嵌套两个动画

java - 使用 GridBagConstraints 更新布局

vb.net - 如何编写 VB.Net Lambda 表达式

java - 通用方法,多个括号,类型

Java Lambda 方法引用 - 需要清楚

java - 如何缩短具有多个字段的比较器?

sql - Sybase - 对 IN 子句使用参数

c# - 具有大量参数的 DAL 方法

mysql - MySQL的rs报表设计参数化查询