当前位置: 首页 > 面试题库 >

为什么在Java 8中按顺序收集并行流

岑光熙
2023-03-14
问题内容

为什么总是forEach以随机顺序打印数字,而collect始终从原始顺序收集元素,即使是从并行流中呢?

Integer[] intArray = {1, 2, 3, 4, 5, 6, 7, 8};
List<Integer> listOfIntegers = new ArrayList<>(Arrays.asList(intArray));

System.out.println("Parallel Stream: ");
listOfIntegers
  .stream()
  .parallel()
  .forEach(e -> System.out.print(e + " "));
System.out.println();

// Collectors         
List<Integer> l = listOfIntegers
  .stream()
  .parallel()
  .collect(Collectors.toList());
System.out.println(l);

输出:

Parallel Stream: 
8 1 6 2 7 4 5 3 
[1, 2, 3, 4, 5, 6, 7, 8]

问题答案:

这里有两种不同的“排序”,使讨论变得混乱。

一种是 遇到顺序 ,该 顺序
在流文档中定义。考虑这一点的一种好方法是源集合中元素的 空间 顺序或 从左到右的
顺序。如果源是List,请考虑将较早的元素放在较后的元素的左侧。

还有文档中未定义的 处理时间
顺序,但这是由不同线程处理元素的时间顺序。如果列表的元素由不同的线程并行处理,则线程可能在列表中最右边的元素之前处理最右边的元素。但是下次可能不会。

即使并行执行计算,大多数Collectors和某些终端操作也会精心安排,以便它们保留从源到目的地的 遇到 顺序 ,而与不同线程处理每个元素的
时间顺序 无关。

需要注意的是,forEach终端的操作并 不能
保留相遇秩序。相反,它由发生任何下一个结果的线程运行。如果您想要这样的东西forEach来保留相遇顺序,请forEachOrdered改用。

另请参阅Lambda常见问题解答,以进一步了解订购问题。



 类似资料:
  • 问题内容: 我正在阅读一本关于线程/同步的简单示例,该书声称使用会允许在同一实例上调用一个线程来访问该方法。它确实按照承诺进行了序列化,但似乎在 下面的方法中创建的第三个数组的大约9/10倍于第二个数组。该代码是示例代码,显示了没有同步方法的问题。 这本书说明了两种方式来处理这个问题,他们是- 并且 很显然,这两种选择工作,因为,相对于原来的代码,括号内的字都像一致… [您好] [世界](大约90

  • 考虑到我有2个CPU核心的事实,并行版本不是应该更快吗?有人能给我一个提示为什么并行版本比较慢吗?

  • 问题内容: 我有以下查询: 我有以下问题: USING语法与ON语法同义吗? 这些联接是从左到右评估的吗?换句话说,此查询是否说:x =公司加入了用户;y = x JOIN工作;z = y加入用户帐户; 如果对问题2的回答为“是”,那么可以安全地假设“公司”表中包含“公司ID”,“用户ID”和“工作ID”列? 我不明白在引用别名“ j”时,如何使用WHERE子句来选择公司表上的行 任何帮助,将不胜

  • 是否有任何保证在顺序和有序流上的操作是按遇到顺序处理的? 我是说,如果我有这样的代码: 是否可以保证它将按照生成范围的遇到顺序执行myFunction()调用? 我找到了Stream类的JavaDocs草案,它明确地说明了以下内容: 对于顺序流管道,如果管道源具有已定义的遇到顺序,则所有操作都按照管道源的遇到顺序执行。 但是它没有提到顺序流,这个例子是针对并行流的(我的理解是,顺序流和并行流都是正

  • 我有2个子项目的java项目。像这样的结构 我只需要在root buiild.gradle中创建'deploy'任务,然后执行以下操作: null 我看到错误“no-source”,但是文件夹“client/build/libs”和“server/build/libs”存在并包含jar。我可以肯定,因为手动运行任务‘复制文件’创建文件夹‘目标’和复制所有文件。我看到的唯一可能的选项是“复制文件”任

  • 问题内容: 我正在使用Node.js运行服务器,并且需要从正在运行的另一台服务器()请求数据。我需要向数据服务器发出许多请求(〜200)并收集数据(响应大小从〜20Kb到〜20Mb不等)。每个请求都是独立的,我想将响应保存为以下形式的一个巨大数组: 请注意,项目的顺序并不重要,理想情况下,它们应该以数据可用的顺序填充数组。 现在,当运行该程序时,它将显示: 现在,由于文件的大小如此可变,我期望它可