java 8流中的副作用

时间:2016-10-19 10:45:30

标签: java-8 java-stream side-effects

Oracle文档中有几件我无法完全理解的内容:

Operations like forEach and peek are designed for side effects;

“设计”是什么意思?这两个人有什么特别之处?我可以编写我的代码,以便任何流API方法通过副作用工作。据我所知,这完全取决于我。更重要的是,我通常会使用peek()来修改元素的状态,而不是源本身,这不会使其变为有状态或副作用。

forEach的javadoc也说:

The behavior of this operation is explicitly nondeterministic.

当他们对findAny说同样的话时我明白了,但对于forEach有什么不确定性?如果未对流进行排序,则并行流中的任何操作都不能保证排序。为什么只为forEach提到了非确定性(和finAny,但它意味着有点不同)?

对于peek和forEach,javadoc还包含:

action may be performed at whatever time and in whatever thread the library chooses

再次,为什么只有那里?为什么不提及其余的操作呢?

1 个答案:

答案 0 :(得分:5)

首先,修改对象状态也是一个副作用,因为程序的整体状态在执行lambda后会发生变化。如果在并行流中多次使用相同的对象,则甚至可能存在并发问题。无副作用函数是一种不改变程序状态的函数,其返回值仅基于其参数。由于其他流操作需要无副作用,因此不必在哪个线程中提及它们将被执行,因为这无关紧要。但如果允许操作产生副作用,则应明确提及。

即使流是无序的,forEach也不同于forEachOrderedforEachOrdered始终保证其lambda不会一次在多个不同的线程中并发执行。 forEach调用不仅会使您的流隐式无序,而且还会删除此保证:您的lambda现在可以同时执行。由于lambda可能产生副作用,因此应明确提及。