小编Nir*_*rro的帖子

如何懒惰地评估嵌套的 flatMap

我试图从两个潜在的无限流中召唤一个笛卡尔积,然后我通过limit().

到目前为止,这(大约)是我的策略:

@Test
void flatMapIsLazy() {
        Stream.of("a", "b", "c")
            .flatMap(s -> Stream.of("x", "y")
                .flatMap(sd -> IntStream.rangeClosed(0, Integer.MAX_VALUE)
                    .mapToObj(sd::repeat)))
            .map(s -> s + "u")
            .limit(20)
            .forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)

这不起作用。

显然,我的第二个流在第一次在管道上使用时就被当场进行了最终评估。它不会产生我可以按照自己的节奏使用的惰性流。

我认为.forEach这段代码中的原因ReferencePipeline#flatMap是:

@Override
public void accept(P_OUT u) {
    try (Stream<? extends R> result = mapper.apply(u)) {
        if (result != null) {
            if (!cancellationRequestedCalled) {
               result.sequential().forEach(downstream);
            }
            else {
                var s = result.sequential().spliterator();
                do { } while (!downstream.cancellationRequested() && s.tryAdvance(downstream));
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望上面的代码返回 20 …

java cartesian-product lazy-evaluation java-stream

14
推荐指数
1
解决办法
312
查看次数