Java 蓄能器在平行流中工作不正常

Java 蓄能器在平行流中工作不正常,java,java-8,java-stream,collectors,Java,Java 8,Java Stream,Collectors,我制作了一个收集器,它可以将一个流简化为一个地图,地图上的键是某些客户可以购买的物品,而客户的名字是值。我的实现在顺序流中很可能工作 但是当我尝试使用parallel时,它根本不起作用,结果集总是包含一个客户名称 List<Customer> customerList = this.mall.getCustomerList(); Supplier<Object> supplier = ConcurrentHashMap<String,Set<String&g

我制作了一个收集器,它可以将一个流简化为一个地图,地图上的键是某些客户可以购买的物品,而客户的名字是值。我的实现在顺序流中很可能工作 但是当我尝试使用
parallel
时,它根本不起作用,结果集总是包含一个客户名称

List<Customer> customerList = this.mall.getCustomerList();

Supplier<Object> supplier = ConcurrentHashMap<String,Set<String>>::new;

BiConsumer<Object, Customer> accumulator = ((o, customer) -> customer.getWantToBuy().stream().map(Item::getName).forEach(
            item -> ((ConcurrentHashMap<String,Set<String>>)o)
                    .merge(item,new HashSet<String>(Collections.singleton(customer.getName())),
                            (s,s2) -> {
                                HashSet<String> res = new HashSet<>(s);
                                res.addAll(s2);
                                return res;
                            })
    ));

BinaryOperator<Object> combiner = (o,o2) -> {
        ConcurrentHashMap<String,Set<String>> res = new ConcurrentHashMap<>((ConcurrentHashMap<String,Set<String>>)o);
        res.putAll((ConcurrentHashMap<String,Set<String>>)o2);
        return res;
    };

Function<Object, Map<String, Set<String>>> finisher = (o) -> new HashMap<>((ConcurrentHashMap<String,Set<String>>)o);

Collector<Customer, ?, Map<String, Set<String>>> toItemAsKey =
        new CollectorImpl<>(supplier, accumulator, combiner, finisher, EnumSet.of(
            Collector.Characteristics.CONCURRENT,
            Collector.Characteristics.IDENTITY_FINISH));

Map<String, Set<String>> itemMap = customerList.stream().parallel().collect(toItemAsKey);
List customerList=this.mall.getCustomerList();
供应商=ConcurrentHashMap::新建;
双消费者累加器=((o,customer)->customer.getWantToBuy().stream().map(Item::getName).forEach(
项目->((ConcurrentHashMap)o)
.merge(项,新哈希集(Collections.singleton(customer.getName())),
(s,s2)->{
HashSet res=新的HashSet;
res.addAll(s2);
返回res;
})
));
二进制运算符组合器=(o,o2)->{
ConcurrentHashMap res=新的ConcurrentHashMap((ConcurrentHashMap)o);
res.putAll((ConcurrentHashMap)o2);
返回res;
};
函数finisher=(o)->新的HashMap((ConcurrentHashMap)o);
收集器toItemAsKey=
新收集器MPL(供应商、累加器、合路器、精整器、枚举集)(
Collector.Characteristics.CONCURRENT,
收集器、特征、标识(表面处理);
Map itemMap=customerList.stream().parallel().collect(toItemAsKey);

我的
累加器
实现或另一个
函数
中肯定有问题,但我无法解决!有人能建议我该怎么做吗?

您的组合器没有正确实现。
覆盖具有相同密钥的所有条目。您需要的是向现有键添加值

BinaryOperator<ConcurrentHashMap<String,Set<String>>> combiner = (o,o2) -> {
        ConcurrentHashMap<String,Set<String>> res = new ConcurrentHashMap<>(o);
        o2.forEach((key, set) -> set.forEach(string -> res.computeIfAbsent(key, k -> new HashSet<>())
                                                          .add(string)));
        return res;
    };
二进制运算符组合器=(o,o2)->{
ConcurrentHashMap res=新的ConcurrentHashMap(o);
o2.forEach((key,set)->set.forEach(string->res.computeifassent(key,k->newhashset())
。添加(字符串));
返回res;
};

一般问题:你真的有太多的数据以至于并行执行在理论上也有意义吗?在我这里的需求中,我没有那么多数据,但我想练习如何使
并发
采集器
为什么你要使用
对象
作为所有函数的类型参数,当它应该是
ConcurrentHashMap
时,只是在每个函数中执行类型转换?此外,当实际的finisher函数不是IDENTITY函数时,不要指定
IDENTITY\u FINISH
。此外,不要使用类似于
CollectorImpl
的类;只要给(…)的收集器打电话就可以了。谢谢你的建议,我会仔细考虑的。这就是我所缺少的
putAll
from
Map
不是组合器中使用的适当方法,谢谢