当前位置: 首页 > 知识库问答 >
问题:

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

越雨泽
2023-03-14

我试图理解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);

    }
}

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

共有1个答案

鲁才艺
2023-03-14

问题是您使用Stream::reduce进行可变缩减,这是专门为其设计Stream::collect。它既可以用于安全并行存储,也可以用于并行存储。阅读Oracle官方文档流:缩减中的差异。与reduce方法不同,reduce方法在处理元素时总是创建新值,collect方法修改或变异现有值。

注意这两种方法在JavaDoc中的区别:

>

  • 减少(U标识,BiFunction

    对该流的元素执行可变缩减操作。

    因此,我建议您采取以下措施:

    StringBuilder concat = Arrays.stream(grades)
        .parallel()
        .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
    

  •  类似资料:
    • 我正在处理大量的4K图像,通过在图像的小(64x64像素)补丁上计算一个参数。这项任务现在是按顺序进行的,一个补丁一个补丁。下面复制了一段我的代码来向您展示这个想法。 结果: 顺序:15754毫秒 并行:5899 ms

    • 我需要将regex列表应用于字符串,所以我想使用java8 map reduce: 实际上,这段代码可能不是很漂亮,但它很有效。我知道这是无法并行的,对我来说是可以的。 现在我的问题是:Java8(或更高版本)是否有机会写出更优雅的东西?我的意思是避免添加无用的组合器功能。

    • 问题内容: 我正在尝试编写一个小型节点应用程序,该应用程序将搜索并解析文件系统上的大量文件。为了加快搜索速度,我们尝试使用某种类型的map reduce。该计划将是以下简化方案: Web请求带有搜索查询 启动3个进程,每个进程分配1000个(不同)文件 进程完成后,它将“返回”结果回到主线程 一旦所有进程完成,主线程将通过返回组合结果作为JSON结果来继续 我对此有以下疑问: 这在Node中可行吗

    • 问题内容: 我想处理对象中的列表。我必须确保处理所有元素,以便收到它们。 因此l,我应该使用它吗? 还是只要不使用并行性就足以使用流? 问题答案: 你在问错问题。你正在询问而要按顺序处理项目,因此你必须询问订购。如果你有顺序的流并执行保证维持顺序的操作,则该流是并行处理还是顺序处理都没有关系;实施将维持秩序。 有序属性不同于并行与顺序。例如,如果你调用一个同时调用流将是无序在List返回的有序流。

    • 我想在Java对象中处理列表。我必须确保处理所有的元素,以便我收到他们。 因此,我是否应该对我使用的每个调用? 或者,只要不使用并行性,只使用流就足够了吗?

    • 问题内容: 给出以下代码: 我可以假设’dowork’函数将并行执行吗? 这是实现并行性的正确方法,还是对每个goroutine使用通道并将单独的“ workwork”工人分开更好? 问题答案: 关于GOMAXPROCS,您可以在Go 1.5的发行文档中找到: 默认情况下,Go程序在将GOMAXPROCS设置为可用内核数的情况下运行;在以前的版本中,它默认为1。 关于防止main功能立即退出,您可