流中间操作排序 [英] Stream intermediate operations ordering
问题描述
是否可以保证在使用流时,中间操作将按程序顺序执行?我怀疑是这种情况,或者它会导致非常微妙的错误,但我找不到明确的答案。
Is there a guarantee that, when working with a stream, intermediate operations will be executed in program order? I suspect it is the case or it would lead to very subtle bugs but I could not find a definite answer.
示例:
List<String> list = Arrays.asList("a", "b", "c");
List<String> modified = list.parallelStream()
.map(s -> s + "-" + s) //"a-a", "b-b", "c-c"
.filter(s -> !s.equals("b-b")) //"a-a", "c-c"
.map(s -> s.substring(2)) //"a", "c"
.collect(toList());
这是否保证始终返回 [a,c]
或 [c,a]
? (如果最后一个映射操作在第一个映射操作之前执行,则可能抛出异常 - 类似地,如果在第二个映射操作之后执行过滤器,则b将保留在最终列表中)
Is this guaranteed to always return ["a", "c"]
or ["c", "a"]
? (if the last map operation is executed before the first map operation, that could throw an exception - similarly if the filter is executed after the second map operation, "b" will be retained in the final list)
推荐答案
您的问题出现了,因为您正在从一种类型映射到同一类型。如果您考虑正在执行的正式操作,很明显无法更改指定操作的顺序:
Your question arose because you are mapping from one type to the same type. If you think about the formal operations you are performing, it becomes clear that there is no way to change the order of the specified operations:
- 您将
流< A>
的项目映射到任意类型B
创建流< B>
- 您对第一个映射的结果应用
过滤器< B>
- 您将已过滤的
流< B>
映射到任意类型C
创建流< C>
- 您将
C
类型的项目收集到列表< C>
- you map items of a
Stream<A>
to an arbitrary typeB
creating aStream<B>
- you apply a
Filter<B>
on the result of the first mapping - you map the filtered
Stream<B>
to an arbitrary typeC
creating aStream<C>
- you collect the items of type
C
into aList<C>
看看这些正式步骤,应该清楚那里由于类型兼容性要求,无法更改这些步骤的顺序。
Looking at these formal steps it should be clear that there is no way to change the order of these steps due to the type compatibility requirements.
在您的特殊情况所有三种类型的事实发生要字符串
不会改变 Stream
的工作原理。请记住,用于类型参数的实际类型将被删除,并且在运行时不存在。
The fact that in your special case all three types happen to be String
does not change the logic of how the Stream
s work. Keep in mind that the actual types you are using for the type parameters are erased and do not exist at runtime.
Stream
实施可能强制执行有用的操作,例如一次性执行排序
和 distinct
,但这要求对相同的项目请求两个操作并且比较
。或者简单地说,内部优化不得改变所请求操作的语义。
The Stream
implementation may coerce operations where it is useful, e.g. performing a sorted
and distinct
in one go but this requires that both operations are requested on the same items and Comparator
. Or simply said, internal optimizations must not change the semantics of the requested operations.
这篇关于流中间操作排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!