代码之家  ›  专栏  ›  技术社区  ›  Rui

为什么用可变对象作为标识在并行流中调用reduce方法不会保留结果的顺序?

  •  3
  • Rui  · 技术社区  · 7 年前

    有以下看似“正确”的代码:

    List<String> list = Arrays.asList("1","2","3","4","5","6",
        "7","8","9","10","11","12");
    String result = list.parallelStream()
       .reduce(new StringBuilder(), StringBuilder::append, 
           StringBuilder::append).toString();
    System.out.println(result);
    

    这个片段的问题是 身份 new StringBuilder() ,在 reduce 方法调用为 因此 result 破坏 ,即 结果 不保存。但是我不能完全理解原因,因此我不能想象一个产生 结果 list . 所以我画了相应的 图,碰巧得到了 结果 enter image description here

    问题:首先,我想确认这个图表是正确的。第二,如果这个图是正确的,我想知道这个代码片段不总是产生 结果

    1 回复  |  直到 5 年前
        1
  •  4
  •   Thomas Kläger    7 年前

    你的图表是不正确的-你假设每一个平行的减少从一个新的开始 StringBuilder 具有相同的标识元素 -使用相同的StringBuilder(创建并作为第一个参数传递给 reduce

    每个并行流调用 StringBuilder.append 在传递给 减少 方法,从而将当前遇到的元素附加到它。

    下一步是组合部分结果,也可以调用 StringBuilder.append文件 在同一个StringBuilder上,将StringBuilder内容的副本附加到自身上。


    Supplier<StringBuilder> 作为reduce操作的第一个参数。

    Mutable Reduction .

    collect 方法:

    List<String> list = Arrays.asList("1","2","3","4","5","6",
        "7","8","9","10","11","12");
    String result = list.parallelStream()
       .collect(StringBuilder::new, StringBuilder::append, 
           StringBuilder::append).toString();
    System.out.println(result);
    
    推荐文章