java - java流中遇到顺序保存

标签 java java-8 java-stream

我已经解决了相关问题,例如 How to ensure order of processing in java8 streams? ,我仍然不完全清楚输出元素的顺序。因此请澄清我的以下疑问。

 Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8 };
            List<Integer> listOfIntegers =
                new ArrayList<>(Arrays.asList(intArray));
       listOfIntegers
            .parallelStream()
             .unordered()
            .forEachOrdered(e -> System.out.print(e + " "));

我认为至少理论上(或根据java规范)它可以按1、2、3、4、5、6、7、8的随机顺序打印。我对吗?

还有一个相关问题——遇到订单保存的决定是在什么执行点做出的? 更准确地说,整个流管道的 ORDER 特性的评估是否是在执行开始之前就通过源、中间操作和终端操作的特性来完成的?

最佳答案

源的无序性质或通过 unordered() 显式释放订单契约可能会影响所有后续管道阶段,除非它们引入只能在 sorted< 中发生的订单 操作。

对于像filtermap这样的无状态中间操作,无论如何都没有区别,但是像skiplimit这样的操作code> 和 distinct 可能会表现出不同的行为,具体取决于先前的流状态是有序的还是无序的。 This answer显示了一个示例,说明 distinct 如何受到先前的 unordered() 的影响。

请注意,原则上,sorted在引入顺序时,可能取决于前一阶段的有序状态,因为如果前一流无序,它可能会使用不稳定的排序算法。

This answer提供了一种方法来打印流的特征并评估它们如何由于附加另一个操作而发生变化。

当您链接终端操作时,终端操作本身的无序性质或终端操作之前最后阶段的无序状态可能足以为终端操作选择一种不尝试保留的算法订单。

原则上,终端操作的无序性质可用于影响前面的阶段,但由于无状态中间操作无论如何都不会受到影响,并且skiplimitdistinct 必须遵守先前的有序状态,如果存在,唯一可能受影响的操作是 sorted,如果后续操作无论如何都不关心顺序,则该操作将变得过时.

在当前实现中,自 Java 8 update 60 起,终端操作的无序性质不会影响之前阶段的行为。与之前的实现一样,进行了此更改,它错误地影响了 skiplimit。失去消除过时排序步骤的机会并不被认为是一个问题,因为将 sort 与无序的后续操作链接起来是一种特殊情况。请参阅this answer ,包括评论,如果您想了解更多相关讨论。

所以对于

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 特征?”是,是的,这是在开始实际处理之前完成的,当有选择时,通过为管道阶段选择适当的算法,但此过程不一定会导致整个管 Prop 有单一特征。

关于java - java流中遇到顺序保存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45085055/

相关文章:

java - Python 是否可以替代在 Java EE 中完成的 Web 应用程序?

java - unicode 格式的日语文本

java - 增加 SequenceFileInputFormat 的分割数

java - 执行单元测试完成的一些高级操作?

java - 从嵌套列表创建 map

foreach - 迭代嵌套集合以查找与条件匹配的第一个子子子元素

java - 如何使用 Java 8 流返回可选字符串

java - Java中如何检查一个元素是否是一个类的实例?

带状态的 Java Streams - 一个简单的练习

java - 如何在 Java 中实现没有资源泄漏警告的 Stream<E>