gpt4 book ai didi

java - 在Java中使用并行流但没有得到预期的值

转载 作者:行者123 更新时间:2023-12-02 02:09:25 26 4
gpt4 key购买 nike

我有一个关于字数统计的代码片段:

    String[] wordCountArr = {"a", "b", "c", "a", "a", "b", "c", "d", "e"};
Stream.of(wordCountArr).collect(TreeMap::new,
(treeMap, str) -> {

Object countValue = treeMap.get(str);
if (countValue != null) {
Integer count = Integer.valueOf(countValue.toString());
treeMap.put(str, count + 1);
}
else {
treeMap.put(str, 1);
}
}, (treeMap, treeMap2) -> {
treeMap.putAll(treeMap2);
}).entrySet()
.forEach(System.out::println);

得到了期望值:a=3 b=2 c=2 d=1 e=1,但是collect函数的Combiner似乎没有执行。然后我得到了这个:Java 8 Stream - Reduce function's combiner not getting executed并将代码更改为:

    Stream.of(wordCountArr).parallel().collect(TreeMap::new,
(treeMap, str) -> {

Object countValue = treeMap.get(str);
if (countValue != null) {
Integer count = Integer.valueOf(countValue.toString());
treeMap.put(str, count + 1);
}
else {
treeMap.put(str, 1);
}
}, (treeMap, treeMap2) -> {
treeMap.putAll(treeMap2);
}).entrySet()
.forEach(System.out::println);

但结果不是预期的:a=1 b=1 c=1 d=1 e=1,我想也许 putAll 函数只是替换旧的映射。有什么好主意可以得到正确的结果吗?使用并行流是否更有效?谢谢!

已解决:

What is the best practices to merge two maps将 putAll 替换为 merge

最佳答案

只有当您使用并行流时框架尝试连接多个fork的结果时,组合器才会执行。

因此在第一个版本中,组合器不会执行。

您的第二个版本的代码可能会导致 ConcurrentModificationException,因为您的 TreeMap 在使用并行流时不是线程安全的。

还有一点是,当您组合两棵树时,您忘记了将两棵树中的值相加。您将 treeMap 的所有内容与 treeMap2 合并,因此 treeMap 中的当前值将被丢弃:treeMap.putAll(treeMap2);

您必须手动迭代 treeMap 中的键,将值与 treeMap2 相加并放回。

我不知道你为什么想出这种方法,但要计算每个组的项目数,你可以简单地使用groupingBy:

Map<String, Long> countMap = Stream.of(wordCountArr).collect(Collectors.groupingBy(Function.identity(), 
Collectors.counting()));

关于java - 在Java中使用并行流但没有得到预期的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50245480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com