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

收集器和合并器在collect中有什么区别?[副本]

穆歌者
2023-03-14

为什么并行流使用合并器类,而顺序流将使用累加器?为什么并行流不使用累加器?

package Streams;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Collect
{
    public static class Debug
    {
        public static void log(Object ... objects)
        {
            for(Object object : objects) {
                System.out.println(object);
            }
        }
    }

    public static void main(String[] args)
    {
        parallel();
        Debug.log("---------------");
        sequential();
    }

    public static void parallel()
    {
        List<Integer> list = Stream.of(1,2,3,4)
                .parallel()
                .collect(
                        ArrayList::new,
                        (a,b)-> {
                            Debug.log("From accumulator",a,b);
                            a.add(b);
                        },
                        (a,b) -> {
                            Debug.log("From combiner",a,b);
                            a.addAll(b);
                        }
                );
    }

    public static void sequential()
    {
        List<Integer> list = Stream.of(1,2,3,4)
                .collect(
                        ArrayList::new,
                        (a,b)-> {
                            Debug.log("From accumulator",a,b);
                            a.add(b);
                        },
                        (a,b) -> {
                            Debug.log("From combiner",a,b);
                            a.addAll(b);
                        }
                );
    }
}

以下是上述代码的输出:

From accumulator
[]
From accumulator
From accumulator
From accumulator
[]
[]
1
4
3
[]
2
From combiner
From combiner
[3]
[1]
[4]
[2]
From combiner
[1, 2]
[3, 4]
---------------
From accumulator
[]
1
From accumulator
[1]
2
From accumulator
[1, 2]
3
From accumulator
[1, 2, 3]
4

那么,为什么顺序流使用累加器,并行流使用组合器?并行流不能使用累加器吗?

共有1个答案

袁子瑜
2023-03-14

组合器的工作似乎是组合为每个线程创建的不同List对象(使用并行)。

    public static void parallel()
    {
        List<Integer> list = Stream.of(1,2,3,4)
                .parallel()
                .collect(
                        ArrayList::new,
                        (a,b)-> {
                            Debug.log("From accumulator",a,b);
                            a.add(b);
                        },
                        (a,b) -> {
                            Debug.log("From combiner",a,b);
                            a.addAll(b);
                        }
                );
    }

因此,在上面的示例中,对于1,2,3,4,将为每个元素创建一个新的数组列表,因为它们在不同的线程上并行运行。因此,组合器将4个现有的阵列列表组合成一个。

 类似资料:
  • groupingBy和Mapping可以互换吗?他们有什么不同? 对于collect()中的第三个参数,如果我使用collectors.toList()而不是collectors.toSet(),会得到相同的输出类型映射吗?我听说toList()是一个更流行的选项。

  • 我正在为新手程序员编写一个库,所以我试图保持API尽可能干净。 我的库需要做的事情之一是对大量的ints或long集合执行一些复杂的计算。我的用户需要从许多场景和业务对象中计算这些值,因此我认为最好的方法是使用流来允许用户将业务对象映射到或,然后在收集器中计算这些计算。 所以与其能够做到 我必须提供这样的供应商、累加器和组合器: 这对我的新手用户来说太复杂了,而且很容易出错。 在使用或的同时,是否

  • 我试图了解两者之间是否有任何重大差异。在查看示例时,我注意到它使用了完全相同的二进制和arg(https://github.com/open-telemetry/opentelemetry-collector/blob/main/examples/demo/docker-compose.yaml). 唯一的区别是配置文件在导出器/接收器方面有所不同。因此,唯一的区别是使用什么endpoint来收集

  • 容器和Docker中的图像有什么区别?在“开始使用Docker”教程中,这两个术语都使用过,但我不理解它们之间的区别。 有谁能说点什么吗?

  • 问题内容: 我正在关注Go教程,由于无法理解特定的方法签名而陷入困境: 该文档解释如下: 该方法的签名如下:“这是一个名为save的方法,它的接收方p是指向Page的指针。它不带参数,并且返回错误类型的值。” 我不明白接收器是什么。我将其作为参数读取,但随后我期望参数位于中。 问题答案: 接收者是声明方法的对象。 要向对象添加方法时,请使用此语法。 例如:http://play.golang.or

  • 这两个子句的主要区别是参数传递。对于< code>IFNULL是两个参数,对于< code>COALESCE是多个参数。所以除此之外,这两者之间还有其他区别吗? 它在MS SQL中有何不同?