来源的无序性质或通过以下方式显式发布订单合同unordered()
可能会影响所有后续的管道阶段,除非它们引入了只能在以下情况下发生的顺序:sorted
手术。
对于无状态中间操作,例如filter
and map
,无论如何没有区别,但是像这样的操作skip
, limit
and distinct
根据先前的流状态是有序的还是无序的,可能会表现出不同的行为。这个答案举例说明如何distinct
可能会受到之前的影响unordered()
.
请注意,原则上,sorted
在引入顺序时,可能取决于前一阶段的有序状态,因为如果前一流是无序的,则可能会使用不稳定的排序算法。
这个答案提供了一种方法来打印流的特征并评估它们如何由于附加另一个操作而发生变化。
当您链接终端操作时,终端操作本身的无序性质或终端操作之前最后阶段的无序状态可能足以为终端操作选择一种不尝试保留顺序的算法。
原则上,终端操作的无序性质可用于影响前面的阶段,但由于无状态中间操作无论如何都不会受到影响,并且skip
, limit
, distinct
必须遵守先前的有序状态,如果存在,唯一可能受到影响的操作是sorted
如果后续操作无论如何都不关心顺序,那么它就会过时。
在当前的实现中,自 Java 8 update 60 以来,终端操作的无序性质不会影响之前阶段的行为。与之前的实现一样,进行了此更改,它错误地影响了skip
and limit
。失去消除过时排序步骤的机会并不被认为是一个问题,因为链接sort
对于无序的后续操作,是一种特殊情况。看这个答案,包括评论,如果您想了解更多相关讨论。
So for
list.stream() // List.stream() returns an ordered stream
.unordered() // releases order contract
.distinct() // for equal elements, it may pick an arbitrary one
.sorted() // re-introduces an order
.skip(1) // will skip the minimum element due to the order
.forEach(System.out::println); // may print the remaining elements in arbitrary order
流管道没有单一的有序或无序行为。
与...对比
hashSet.stream() // HashSet.stream() has no order (unless being a LinkedHashSet)
.filter(Objects::nonNull) // not affected by order
.distinct() // may use unorderedness, but has no effect anyway, as already distinct
.skip(1) // may skip an arbitrary element
.forEachOrdered(System.out::println); // would respect order if there was one
整个管道无序运行,只是因为源是无序的。有了有序源,它就会完全有序。
所以答案是“整个流管道ORDER特性的评估是否是在执行开始之前就通过源、中间操作和终端操作的特性来完成的?是的,这是在开始实际处理之前完成的,当有选择时,通过为管道阶段选择适当的算法,但此过程不一定会产生整个管道的单一特征。