简而言之:
排序取决于源数据结构和中间流操作。假设您使用的是List,则应订购处理(因为filter 不会在此处更改顺序)。
更多细节:
顺序 vs 并行 vs 无序:
Javadocs
S sequential()
Returns an equivalent stream that is sequential. May return itself, either because the stream was already sequential, or because the underlying stream state was modified to be sequential.
This is an intermediate operation.
S parallel()
Returns an equivalent stream that is parallel. May return itself, either because the stream was already parallel, or because the underlying stream state was modified to be parallel.
This is an intermediate operation.
S unordered()
Returns an equivalent stream that is unordered. May return itself, either because the stream was already unordered, or because the underlying stream state was modified to be unordered.
This is an intermediate operation.
流排序:
Javadocs
流可能有也可能没有定义的相遇顺序。
流是否有遇到顺序取决于来源
和中间操作。某些流源(例如 List
或数组)本质上是有序的,而其他(如 HashSet)
不是。一些中间操作,例如 sorted(),可能会强加一个
在其他无序的流上遇到顺序,其他人可能
无序渲染有序流,例如 BaseStream.unordered()。
此外,一些终端操作可能会忽略遇到顺序,例如
forEach().
如果流是有序的,大多数操作都被限制在
遇到顺序中的元素;如果流的源是
列表包含 [1, 2, 3],然后是执行 map(x -> x*2) 的结果
必须是 [2, 4, 6]。但是,如果源没有定义的遭遇
顺序,那么值 [2, 4, 6] 的任何排列都是有效的
结果。
对于顺序流,是否存在相遇顺序
不影响性能,只影响确定性。如果流是有序的,
在相同的流水线上重复执行相同的流管道
source 将产生相同的结果;如果没有订购,
重复执行可能会产生不同的结果。
对于并行流,有时可以放宽排序约束
实现更高效的执行。某些聚合操作,例如
过滤重复项(distinct())或分组减少
(Collectors.groupingBy()) 可以更有效地实现,如果
元素的顺序不相关。同样,操作是
本质上与遇到顺序相关,例如 limit(),可能需要
缓冲以确保正确排序,破坏了
并行性。在流有遇到顺序的情况下,但是
用户并不特别关心遇到的顺序,明确地
使用 unordered() 对流进行降序可能会提高并行性
一些有状态或终端操作的性能。然而,大多数
流管道,例如上面的“块权重总和”示例,
即使在排序约束下仍然有效地并行化。