当前位置: 首页 > 知识库问答 >
问题:

java流中的顺序保持

谭京
2023-03-14

我已经讨论了一些相关问题,比如如何确保java8流中的处理顺序?,我仍然不完全清楚输出元素的顺序。因此,请澄清我的以下疑问。

 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以外的随机顺序打印。我说得对吗?

还有一个相关的问题——遭遇订单保存的决定是在执行的哪个点做出的?更准确地说,在执行开始之前,是否通过检查源、中间操作和终端操作的特性来评估整个流水线的订单特性?

共有2个答案

史飞尘
2023-03-14

一旦你选择了无序,那么最终结果基本上是以随机顺序出现的。请注意,虽然没有要求它这样做,但事实上,您可能仍然会在输出中看到一些排序。

forEachOrdered保留“流”的遭遇顺序,因此如果没有。无序()。如果流已经无序,那么它是毫无意义的,您也可以使用forEach

换句话说,forEachOrdered在已经排序的流中保留遭遇顺序。它不进行任何排序或其他排序,但是如果流已经是无序的,那么任何事情都可能发生。

扶文光
2023-03-14

源代码的无序性质或通过无序()显式释放订单合同可能会影响所有后续管道阶段,除非它们引入了只能通过排序操作发生的订单。

对于无状态的中间操作,如filtermap,无论如何都没有区别,但是像skiplimitdistinct这样的操作可能会表现出不同的行为,这取决于之前的流状态是有序的还是无序的。这个答案展示了一个例子,说明了前一个unordered()如何影响distinct

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

这个答案提供了一种方法来打印流的特征,并评估它们如何因附加另一个操作而改变。

当链接一个终端操作时,终端操作本身的无序性质或终端操作前最后阶段的无序状态可能足以为终端操作选择一个不试图保持顺序的算法。

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

在当前的实现中,自从Java

所以

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

整个管道都是无序运行的,因为源是无序的。有了有序的源,它将是完全有序的。

所以,问题的答案是“整个流管道顺序特性的评估是在执行开始之前通过源、中间操作和终端操作的特性来完成的吗?”是的,这是在开始实际处理之前完成的,通过为管道阶段选择合适的算法,当有选择时,但这个过程不一定会导致整个管道的单一特征。

 类似资料:
  • 问题内容: 我想处理对象中的列表。我必须确保处理所有元素,以便收到它们。 因此l,我应该使用它吗? 还是只要不使用并行性就足以使用流? 问题答案: 你在问错问题。你正在询问而要按顺序处理项目,因此你必须询问订购。如果你有顺序的流并执行保证维持顺序的操作,则该流是并行处理还是顺序处理都没有关系;实施将维持秩序。 有序属性不同于并行与顺序。例如,如果你调用一个同时调用流将是无序在List返回的有序流。

  • 我想在Java对象中处理列表。我必须确保处理所有的元素,以便我收到他们。 因此,我是否应该对我使用的每个调用? 或者,只要不使用并行性,只使用流就足够了吗?

  • 我试图从流中获取订单地图。我有下一个代码: 在这里,我尝试对数据流进行排序,我认为地图也是有序的。但我错了。我认为调用collect(Collectors.toMap())不会保存流的顺序。有我如何做到这一点的例子吗?

  • 我习惯了用Scala编程,但我必须编写一些Java,我正在尝试执行相当于以下Scala片段的操作: 也就是说,我在

  • 我已经讨论了前面的几个问题,比如java stream中的遭遇顺序保存、Brian Goetz的回答,以及javadoc for stream。reduce()和java。util。流包javadoc,但我仍然无法理解以下内容: 以这段代码为例: 为什么减少总是保持遭遇顺序? 到目前为止,经过几十次运行,产量是相同的

  • 问题内容: Java Set是否保留顺序?有一种方法将Set返回给我,并且假定数据是有序的,但是遍历Set时,数据是无序的。有没有更好的方法来解决这个问题?是否需要更改方法以返回Set以外的内容? 问题答案: 该Set接口不提供任何订购保证。 它的子接口代表根据某种标准排序的集合。在Java 6中,有两个实现的标准容器。他们是和。 除了SortedSet接口之外,还有类。它记住元素插入到集合中的顺