在 Java 8 中,reduce() 方法如何处理并行流?

elv*_*vis 3 java arrays stringbuilder java-8 java-stream

我试图了解reduce()方法如何与并行流完全配合,但我不明白为什么以下代码不返回这些字符串的串联。

这是代码:

public class App {

    public static void main(String[] args) {
        String[] grades = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K"};

        StringBuilder concat = Arrays.stream(grades).parallel()
                .reduce(new StringBuilder(),
                        (sb, s) -> sb.append(s),
                        (sb1, sb2) -> sb1.append(sb2));

        System.out.println(concat);

    }
}
Run Code Online (Sandbox Code Playgroud)

该代码仅适用于顺序流,但对于并行流,它不会返回串联。每次输出都不一样。有人可以解释一下那里发生了什么吗?

Nik*_*las 5

问题是您使用了专门Stream::reduceMutable reductionStream::collect设计的。它既可以用于安全的并行存储。也可以在 Oracle 官方文档Streams: Reduction 中了解这些差异。与在处理元素时总是创建新值的 reduce 方法不同,collect 方法修改或改变现有值。

请注意 JavaDoc 中两种方法之间的差异:

因此,我建议您执行以下操作:

StringBuilder concat = Arrays.stream(grades)
    .parallel()
    .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
Run Code Online (Sandbox Code Playgroud)