【问题标题】:Different result when using stream and parallelStream for the reduction of the same array of data?使用流和并行流减少相同数据数组时的结果不同?
【发布时间】:2018-06-20 14:50:01
【问题描述】:

我在具有相同 lambda 表达式的同一个数组上使用 reduce 与 stream 和 parallelStream,我希望得到相同的结果,但输出不同。但是,结果不同,我不知道为什么。

代码:

    System.out.println("Reduce me...");
    Integer[] arrx = {1,2,3,4};
    //        Reducing the Array

    Arrays
            .stream(arrx)
            .reduce((s1, s2) -> (int)Math.pow(s1,2) + (int)Math.pow(s2,2))
            .ifPresent(System.out::println);

    Arrays.asList(arrx)
            .parallelStream()
            .reduce((s1, s2) -> (int)Math.pow(s1,2) + (int)Math.pow(s2,2))
            .ifPresent(System.out::println);

输出:

1172
650

【问题讨论】:

  • 您研究过streamparallelStream 之间的区别吗?如果您已经知道这会导致不同的结果...
  • @Gatusko 这可能不是完全相同的副本,但从这个问题中肯定可以学到很多东西。感谢您的链接。

标签: java java-8


【解决方案1】:

您的reduce 操作取决于数组元素的遇到顺序。

parallelStream 忽略该顺序,并且每次调用并行执行时都会收到不同的值。

【讨论】:

  • 酷,我明白了!谢谢
  • 并行流忽略顺序。它假定您传递一个associative function 来减少,如mandated by the specification。如果你遵守合同,你会得到正确的结果。例如String::concat 取决于元素的顺序,但它是一个关联函数,与并行reduce 完美配合。
【解决方案2】:

顺序流是确定性的,这意味着我们知道它执行的操作序列:

1^2 + 2^2 = 1 + 4 = 5
5^5 + 3^2 = 25 + 9 = 34
34^2 + 4^2 = 1156 + 16 = 1172

并行流可以按任何顺序减少元素。您观察到的 650 可能是通过这些操作产生的:

1^2 + 2^2 = 5
3^2 + 4^2 = 9 + 16 = 25
5^2 + 25^2 = 25 + 625 = 650

下次您可能会得到不同的订单,因此会得到不同的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-08
    • 2021-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 2018-07-19
    • 1970-01-01
    相关资源
    最近更新 更多