在哪些情况下Stream操作应该是有状态的? [英] In which cases Stream operations should be stateful?
问题描述
在 javaodoc for the stream
package ,在 Parallelism
部分的末尾,我读到:
In the javaodoc for the stream
package, at the end of the section Parallelism
, I read:
大多数流操作接受描述用户指定行为的参数,这些参数通常是lambda表达式。为了保持正确的行为,这些行为参数必须是无干扰的,,并且在大多数情况下必须是无状态的。
我很难理解这个在大多数情况下。在哪些情况下可以接受/希望进行有状态流操作?
I have hard time understanding this "in most cases". In which cases is it acceptable/desirable to have a stateful stream operation?
我的意思是,我知道这是可能的,特别是在使用顺序流时,但是相同的javadoc清楚state:
I mean, I know it is possible, specially when using sequential streams, but the same javadoc clearly states:
除了标识为明确不确定的操作外,例如
findAny()
,流是顺序执行还是并行执行不应该改变计算结果。
Except for operations identified as explicitly nondeterministic, such as
findAny()
, whether a stream executes sequentially or in parallel should not change the result of the computation.
还有:
另请注意,尝试从行为参数访问可变状态会使您在安全性和性能方面做出错误选择; [...]最好的方法是避免有状态的行为参数完全流动操作;通常有一种方法可以重构流管道以避免有状态。
Note also that attempting to access mutable state from behavioral parameters presents you with a bad choice with respect to safety and performance; [...] The best approach is to avoid stateful behavioral parameters to stream operations entirely; there is usually a way to restructure the stream pipeline to avoid statefulness.
所以,我的问题是:在哪种情况下它是好的练习使用有状态流操作(而不是用于副作用的方法,例如 forEach
)?
So, my question is: in which circumstances is it a good practice to use a stateful stream operation (and not for methods working by side-effect, such as forEach
)?
一个相关的问题可能是:为什么有副作用的操作,例如 forEach
?我总是为循环做一个好的旧,以避免在我的lambda表达式中产生副作用。
A related question could be: why are there operations working by side effect, such as forEach
? I always end up doing a good old for
loop to avoid having side-effects in my lambda expression.
推荐答案
有状态流lambdas的例子:
Examples of stateful stream lambdas:
-
collect(Collector)
:收集器
按定义是有状态的,因为它必须收集集合(状态)中的所有元素。 -
forEach(消费者)
:消费者
按定义是有状态的,除非它是黑洞(无操作) )。 -
peek(消费者)
:消费者
按定义是有状态的,因为为什么不偷看它(如日志)。
collect(Collector)
: TheCollector
is by definition stateful, since it has to collect all the elements in a collection (state).forEach(Consumer)
: TheConsumer
is by definition stateful, well except if it's a black hole (no-op).peek(Consumer)
: TheConsumer
is by definition stateful, because why peek if not to store it somewhere (e.g. log).
所以,收藏家
和 Consumer
是两个lambda接口,根据定义是有状态的。
So, Collector
and Consumer
are two lambda interfaces that by definition are stateful.
所有其他的,例如 Predicate
,功能
, UnaryOperator
, BinaryOperator
和比较器
,应无国籍。
All the others, e.g. Predicate
, Function
, UnaryOperator
, BinaryOperator
, and Comparator
, should be stateless.
这篇关于在哪些情况下Stream操作应该是有状态的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!