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

将并行阵列流缩减为单个阵列

云令
2023-03-14

我正在尝试减少阵列流的并行流

    public static void main(String [] args) {
        ArrayList<String> l1 = new ArrayList<>();
        l1.add("a1");
        l1.add("a2");
        
        List<String> l2 = new ArrayList<>();
        l2.add("a3");
        l2.add("a4");
                
        List<List<String>> l = new ArrayList<>();
        l.add(l1);
        l.add(l2);
        
        Stream<List<String>> stream = l.stream();
        join(stream).forEach(System.out::println);
}

private  static  <T> List<T> join(Stream<List<T>> stream) {
        return stream.parallel().reduce(new ArrayList<>(),  (total, element) -> {
            System.out.println("total: " + total);
            System.out.println("element: " + element);
            total.addAll(element);
            return total;
        },  (total1, total2) -> {
            System.out.println("total1: " + total1);
            System.out.println("total2: " + total2);
            total1.addAll(total2);
            return total1;
        });
}

我知道合并器用于合并并行流。。但它并没有像我预期的那样工作,因为我得到了如下重复结果:-

total: []
element: [a3, a4]
total: []
element: [a1, a2]
total1: [a3, a4, a1, a2]
total2: [a3, a4, a1, a2]
a3
a4
a1
a2
a3
a4
a1
a2

那么为什么结果是重复的呢?在累加器中使用数组列表是否线程安全?

共有1个答案

澹台权
2023-03-14

您应该只使用平面图

返回一个流,该流由将该流的每个元素替换为通过将提供的映射函数应用于每个元素而生成的映射流的内容的结果组成。每个映射流在其内容放入此流后都会关闭。(如果映射流为空,则使用空流。)

这是一个中间操作。

l.stream().flatMap(x -> x.stream()).collect(Collectors.toList()); // is [a1, a2, a3, a4]

l.stream().flatMap(List::stream).collect(Collectors.toList());

您的代码的问题是您将函数式风格的代码与副作用混合在一起。这不是好兆头。如果您删除副作用,输出将如预期的那样:

    private static <T> List<T> join(Stream<List<T>> stream) {
        return stream.parallel().reduce(new ArrayList<>(), (total, element) -> {
            System.out.println("total: " + total);
            System.out.println("element: " + element);
            //total.addAll(element);
            //return total;
            var list = new ArrayList<T>(total);
            list.addAll(element);
            return list;
        }, (total1, total2) -> {
            System.out.println("total1: " + total1);
            System.out.println("total2: " + total2);
            //total1.addAll(total2);
            //return total1;
            var list = new ArrayList<T>(total1);
            list.addAll(total2);
            return list;
        });
    }

您还应该避免使用parallel(),除非您有明确的客观理由。并行性是一种开销,只有当有繁重的工作要做时,它才会变得更高效。否则,同步开销将是比任何收益都大的代价。

 类似资料:
  • 问题内容: 我需要将几个数组合并为一个数组。描述我要寻找的内容的最好方法是将阵列“交织”为单个阵列。 例如,从数组#1中取出第一项,然后追加到最终数组中。从数组2获取项目1,然后追加到最终数组。从数组#1获得第二项并追加…等。 最终的数组如下所示: array#1.element#1 array#2.element#1。。。 “踢球者”是各个阵列可以具有各种长度。 是否有更好的数据结构要使用? 问

  • 在研究将基元数组转换为流的方法时,我发现不支持,而支持其他基元数组类型。有什么特别的理由把他们排除在外吗?

  • 所以,我正在尝试匹配 2 个不同的数组。如果相同的单元格匹配,我想使用 .slice 方法从一个数组中删除该单元格。 编辑:我想做的是从数组1中移除一个数字,如果数组2包含一个匹配的数字。代码现在的工作方式是只删除1个条目。我要删除第一个数组中的所有条目。 我尝试运行这个,在控制台日志下,array1没有变化。似乎拼接方法没有删除任何单元格。我搜索了SE,但没有找到任何可以帮助我的东西。

  • 例4.5.6...2意味着4个意向转到第一个邮箱,5转到第二个邮箱,以此类推。 我如何给出正确的单元数组形式的输入。由于数据和算法都来自同一个库,我想不知何故,我已经在一个形式中的数据很容易转换成单元数组!

  • 本文向大家介绍MATLAB单元阵列,包括了MATLAB单元阵列的使用技巧和注意事项,需要的朋友参考一下 示例 同一类的元素通常可以连接成数组(有一些罕见的例外,例如函数句柄)。数值标量(默认为class double)可以存储在矩阵中。 char在MATLAB中属于类的字符也可以使用类似的语法存储在数组中。这样的数组类似于许多其他编程语言中的字符串。 请注意,尽管两者都使用方括号[和],结果类却不

  • 当我试图在页面的内容流中添加文本时,我很难理解PDFBox的行为。我使用的是一个样本扫描PDF,它只是一个叠加在页面上的光栅图像。我的PDF内部工作知识有些基础,所以我可能走错了方向。 http://solutions.weblite.ca/pdfocrx/scansmpl.pdf 我将PDFBox 2.0.11与sbt一起使用: 我的第一步是创建一个内容流,并在PDF上写“你好世界”,我通过以下