【问题标题】:How to sort list in parallelStream?如何在parallelStream中对列表进行排序?
【发布时间】:2021-10-14 06:01:34
【问题描述】:

有没有办法使用parallelStream() 对列表进行排序?我看到有forEachforEachOrdered。但是我正在检查是否有一种方法可以如下排序,

list.parallelStream().map().sorted().collect(Collectors.toList());

【问题讨论】:

  • 上面的 sn-p 有什么问题?仅供参考,.sorted()stateful:“在看到流的所有元素之前,无法通过对流进行排序产生任何结果”。
  • 您需要什么帮助?那行得通。

标签: java list sorting parallelstream


【解决方案1】:

并行流只是标准流,因此可以将sorted 应用于并行流。 sorted 方法的结果是一个顺序流。

所以它的工作原理如下:

 list.parallelStream()   // Generate a parallel stream
     .map(item -> ...)   // Item are mapped in parallel
     .sorted()           // sorted needs to wait for all elements before continuing
                         // Here the stream is sequential
     .collect(Collectors.toList());   // Collect to a new list

所以sorted可以对并行流进行操作,但是生成的流是顺序的并且只有在接收到并行流的所有元素后才释放 /strong>。


更新答案(感谢@Louis Wasserman)

排序的结果不是顺序的。终端操作将保持与原始流相同的顺序,而不取决于它是顺序流还是并行流。 所以之前暴露的正确代码必须在cmets中修改如下

 list.parallelStream()   // Generate a parallel stream
     .map(item -> ...)   // Item are mapped in parallel
     .sorted()           // sorted needs to wait for all elements before continuing
                         // REMOVED --> Here the stream is sequential
     .collect(Collectors.toList());   // Collect to a new list
                                      // ADDED --> in the same order of the received after the sorted step

如果在 sorted 之后添加一个 map 操作,执行时间是随机的,你可以看到这个 map 操作可以在不同的时刻结束,但最后 collect 会按照原始顺序生成一个 List。 (感谢 Louis Wasserman...我犯了一个错误,我不知道流的真正内部细节,我希望更新的答案能让您更好地理解流的工作原理)

【讨论】:

  • 你为什么认为流是连续的?并行并不意味着无序。
  • 我编辑答案,用一个基本的例子告诉你
  • .sorted() 的结果 不是 连续的。它确实会等到排序完成,但对它的进一步操作将并行执行。
  • 谢谢@LouisWasserman ...我对流内部的工作方式有一个坏主意。你的cmets让我大开眼界。是否有任何“官方”文档解释它?
  • 非常感谢您的回复。同时也感谢您抽出宝贵时间回答这个问题。
猜你喜欢
  • 1970-01-01
  • 2020-12-23
  • 1970-01-01
  • 2022-01-05
  • 2012-12-16
  • 2019-11-29
  • 1970-01-01
  • 2017-09-14
相关资源
最近更新 更多