java 8 个流中的副作用

Side-effects in java 8 streams

Oracle 文档中有几处我无法完全理解:

Operations like forEach and peek are designed for side effects;

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

forEach 的 javadoc 还说:

The behavior of this operation is explicitly nondeterministic.

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

for peek 和 forEach javadoc 还包含:

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

同样,为什么只有那里?为什么其他操作没有提到它?

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

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