【发布时间】:2011-04-04 19:39:55
【问题描述】:
假设我有两个哈希图:
- {狗=1,猫=1,运动=3,高尔夫=4}
- {狗=5,人=1,动物=4}
我想合并它们并保留值,以便这些值在输出中相加
输出:
{狗=6,人=1,动物=4,猫=1,运动=3,高尔夫=4}
注意“狗”的值是 6 (5+1)
使用 Hashmap.putAll(),dog 的值变为 5, 有什么想法可以合并这些保留值吗?
非常感谢, 菲利普
【问题讨论】:
假设我有两个哈希图:
我想合并它们并保留值,以便这些值在输出中相加
输出:
{狗=6,人=1,动物=4,猫=1,运动=3,高尔夫=4}
注意“狗”的值是 6 (5+1)
使用 Hashmap.putAll(),dog 的值变为 5, 有什么想法可以合并这些保留值吗?
非常感谢, 菲利普
【问题讨论】:
Google 的开源 Guava Library 有一个名为 Multiset 的类,它完全抽象出对 Map<T,Integer> 的需求,用于计算 T 的实例。
您会发现使用Multiset<String> 而不是使用Map<String,Integer> 会减少代码,从而更不容易出错。
使用Multiset,合并两者,你会说:
multiset1.addAll(multiset2);
【讨论】:
Multiset 方法,不是因为它不太“容易出错”,而是因为它似乎是最适合这项工作的数据结构。 :)
HashMap merged = new HashMap<String, Integer>();
for (String x : map1.getKeySet()) {
Integer y = map2.get(x);
if (y == null) {
merged.put(x, map1.get(x));
} else {
merged.put(x, map1.get(x)+y);
}
}
for (String x : map2.getKeySet()) {
if (merged.get(x) == null) {
merged.put(x, map2.get(x));
}
}
只是把它放在一起 - 并不是说这是最好的方法。
【讨论】:
取较大的,沿着较小的循环,添加不存在的条目,并调整现有条目的值。
【讨论】:
如果您将重复的键、值放入 java 中的映射中,它将替换以前存在的任何值。
您可以检查该值是否存在 所以
Map outputMap = new HashMap<String, Integer>()
for(Map.Entry<String, Integer> entry : map1.entrySet()){
if(map2.contains(entry.getKey()){
outputMap.put(entry.getKey(), entry.getValue() + map2.get(entry.getKey());
map2.remove(entry.getKey());
}
else
outputMap.put(entry.getKey(), entry.getValue()
}
outputMap.addAll(map2);
【讨论】:
这将是最简单的非破坏性方法,尽管它可能不如两个循环那样有效,因为两个键集都插入到第三个循环中。
HashSet<String> allKeys = new HashSet<String>();
HashMap<String, Integer> resultMap = new HashMap<String, Integer>();
allKeys.addAll(map1.keySet());
allKeys.addAll(map2.keySet());
for (String k : allKeys) {
int i1 = map1.containsKey(k) ? map1.get(k) : 0;
int i2 = map2.containsKey(k) ? map2.get(k) : 0;
resultMap.put(k, i1 + i2);
}
【讨论】:
你可以缩短循环。
Map<String, Integer> merged = new HashMap<String, Integer>(map1);
for (Map.Entry<String, Integer> entry : map2.entrySet()) {
Integer y = merged.get(entry.getKey());
merged.put(entry.getKey(), entry.getValue() + (y == null ? 0 : y));
}
【讨论】: