Stream.count() 是否保证访问每个元素?

2022-01-22 00:00:00 java-8 java java-stream

换句话说,以下行是否保证打印 num 行?

In other words, is the following line guranteed to print num lines?

int num = list.stream().peek(System.out::println).count();

这个问题是由 https://stackoverflow.com/a/41346586/2513200

我依稀记得一个讨论,避免迭代的优化可能是合法的,但在快速搜索过程中没有找到任何结论.

I vaguely remember a discussion that optimizations that avoid iteration might be legal, but didn't find anything conclusive during a quick search.

JavaDocsStream.count 包含以下语句:

这是归约的一种特殊情况,相当于:
return mapToLong(e -> 1L).sum();

This is a special case of a reduction and is equivalent to:
return mapToLong(e -> 1L).sum();

但我不确定如果流能够以某种短路方式确定结果,这是否能提供任何保证.

but I'm not sure whether this provides any guarantees if the stream can somehow determine the result in a short-circuiting way.

推荐答案

不,不是.由于优化了 count() 实现,它不会在 Java 9 中执行此操作(如果预先知道流大小,它将跳过迭代).

Nope, it's not. It will not do it in Java 9 due to optimized count() implementation (if stream size is known in advance, it will skip iteration).

有关详细信息,请参阅 JDK-8067969.JDK-9<中的文档/a> 已相应更新:

See JDK-8067969 for more details. The documentation in JDK-9 was updated accordingly:

如果实现可以直接从流源计算计数,则可以选择不执行流管道(顺序或并行).在这种情况下,不会遍历源元素,也不会评估任何中间操作.有副作用的行为参数,除了调试等无害的情况外,强烈建议不要使用,可能会受到影响.

An implementation may choose to not execute the stream pipeline (either sequentially or in parallel) if it is capable of computing the count directly from the stream source. In such cases no source elements will be traversed and no intermediate operations will be evaluated. Behavioral parameters with side-effects, which are strongly discouraged except for harmless cases such as debugging, may be affected.

相关文章