【问题标题】:What is the difference between accumulator and combiner in collect? [duplicate]collect中的accumulator和combiner有什么区别? [复制]
【发布时间】:2020-06-21 16:14:17
【问题描述】:

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

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

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

【问题讨论】:

  • 在我看来你的并行使用两者。
  • parallel on stream 使得执行发​​生在不同的线程上,并且要求合并/组合作为强制性步骤发生,而对于顺序流,它全部在一个线程下,因此是累加器在这种情况下,至少足以在管道中执行操作。为了更好地理解这一点,您可以更改为System.out.println(object + " in thread " + Thread.currentThread().getName());
  • 累加器添加一项,例如部分结果 + 流项目。组合器结合了两个部分结果,例如部分结果 + 部分结果。想象一下你的收藏家正在制作一个列表。累加器将一个项目添加到列表中:列表 + 项目。一个 combiner 合并两个 List:List + List

标签: java java-stream


【解决方案1】:

组合器的工作似乎是组合为每个线程创建的不同List-objects(与parallel)。

    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,为每个元素创建了一个新的 ArrayList,因为它们在不同的线程上并行运行。所以combiner将现有的4个ArrayLists合二为一。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2012-03-14
  • 2013-03-28
  • 2016-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多