java - 如何合并多个hashmap也将相同键的值相加
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/28866085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to merge more than one hashmaps also sum the values of same key in java
提问by Melike Ttkn
? am trying to merge more than one hashmaps also sum the values of same key, ? want to explain my problem with toy example as follows
? 正在尝试合并多个哈希图也对相同键的值求和,?想用玩具示例解释我的问题如下
HashMap<String, Integer> m = new HashMap<>();
HashMap<String, Integer> m2 = new HashMap<>();
m.put("apple", 2);
m.put("pear", 3);
m2.put("apple", 9);
m2.put("banana", 6);
? tried putall
? 试过 putall
m.putAll(m2);
m.putAll(m2);
output is as follows {banana=6, apple=9, pear=3}
输出如下 {banana=6, apple=9, pear=3}
but its result is not true for this problem. ? want to output as
但它的结果对于这个问题是不正确的。? 想输出为
{banana=6, apple=11, pear=3}
{香蕉=6,苹果=11,梨=3}
how can ? get this result in java?
怎么能 ?在java中得到这个结果?
回答by prunge
回答by sprinter
This is a very nice use case for Java 8 streams. You can concatentate the streams of entries and then collect them in a new map:
这是 Java 8 流的一个非常好的用例。您可以连接条目流,然后将它们收集在新地图中:
Map<String, Integer> combinedMap = Stream.concat(m1.entrySet().stream(), m2.entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.summingInt(Map.Entry::getValue)));
There are lots of nice things about this solution, including being able to make it parallel, expanding to as many maps as you want and being able to trivial filter the maps if required. It also does not require the orginal maps to be mutable.
这个解决方案有很多好处,包括能够使其平行、扩展到任意数量的地图以及能够在需要时对地图进行微不足道的过滤。它也不要求原始地图是可变的。
回答by Zymus
Here's my quick and dirty implementation:
这是我快速而肮脏的实现:
import java.util.HashMap;
import java.util.Map;
public class MapMerger {
public static void main(String[] args) {
HashMap<String, Integer> m = new HashMap<>();
HashMap<String, Integer> m2 = new HashMap<>();
m.put("apple", 2);
m.put("pear", 3);
m2.put("apple", 9);
m2.put("banana", 6);
final Map<String, Integer> result = (new MapMerger()).mergeSumOfMaps(m, m2);
System.out.println(result);
}
public Map<String, Integer> mergeSumOfMaps(Map<String, Integer>... maps) {
final Map<String, Integer> resultMap = new HashMap<>();
for (final Map<String, Integer> map : maps) {
for (final String key : map.keySet()) {
final int value;
if (resultMap.containsKey(key)) {
final int existingValue = resultMap.get(key);
value = map.get(key) + existingValue;
}
else {
value = map.get(key);
}
resultMap.put(key, value);
}
}
return resultMap;
}
}
Output:
输出:
{banana=6, apple=11, pear=3}
There are some things you should do (like null checking), and I'm not sure if it's the fastest. Also, this is specific to integers. I attempted to make one using generics of the Number
class, but you'd need this method for each type (byte, int, short, longer, etc)
有些事情你应该做(比如空检查),我不确定它是否是最快的。此外,这特定于整数。我尝试使用Number
类的泛型来创建一个,但是对于每种类型(字节、整数、短、长等),您都需要使用此方法
回答by Melike Ttkn
? improve Lucas Ross's code. in stead of enter map by one by in function ? give all maps one times to function with arraylist of hashmap like that
? 改进 Lucas Ross 的代码。而不是在函数中逐个输入地图?给所有映射一次,以使用像这样的哈希映射数组列表
public HashMap<String, Integer> mergeAndAdd(ArrayList<HashMap<String, Integer>> maplist) {
HashMap<String, Integer> result = new HashMap<>();
for (HashMap<String, Integer> map : maplist) {
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String key = entry.getKey();
Integer current = result.get(key);
result.put(key, current == null ? entry.getValue() : entry.getValue() + current);
}
}
return result;
}
}
}
it works too. thanks to everbody
它也有效。感谢所有人
回答by Lucas Ross
This method should do it (in Java 5+)
这个方法应该这样做(在Java 5+中)
public static <K> Map<K, Integer> mergeAndAdd(Map<K, Integer>... maps) {
Map<K, Integer> result = new HashMap<>();
for (Map<K, Integer> map : maps) {
for (Map.Entry<K, Integer> entry : map.entrySet()) {
K key = entry.getKey();
Integer current = result.get(key);
result.put(key, current == null ? entry.getValue() : entry.getValue() + current);
}
}
return result;
}
回答by Petro
Something like this should work:
这样的事情应该工作:
for (Map.Entry<String, Integer> entry : map.entrySet()) {
String map1_key = entry.getKey();
int map1_value = entry.getValue();
//check:
if(map2.get(map1_key)!=null){
int map2_value = map2.get(map1_key);
//merge:
map3.put(map1_key,map1_value+map2_value);
}else{
map3.put(map1_key,map1_value);
}
}
for (Map.Entry<String, Integer> entry2 : map2.entrySet()) {
String map2_key = entry2.getKey();
int map2_value = entry2.getValue();
//check:
if(map1.get(map2_key)!=null){
int map1_value = map1.get(map2_key);
//merge:
map3.put(map2_key,map1_value+map2_value);
}else{
map3.put(map2_key,map2_value);
}
}
回答by ventsyv
If the key exists, add to it's value. If not insert.
如果键存在,添加到它的值。如果没有插入。
Here is a simple example which merges one map into another:
这是一个将一张地图合并到另一张地图的简单示例:
Foo oldVal = map.get(key);
if oldVal == null
{
map2.put(key, newVal);
}
else
{
map2.put(key, newVal + oldVal);
}
Obviously you have to loop over the first map so you can process all of it's entries but that's trivial.
显然,您必须遍历第一张地图,以便您可以处理它的所有条目,但这是微不足道的。
回答by Nano
Assume that you have many HashMaps: HashMap<String,Integer> map1, map2, map3;
假设你有很多 HashMap: HashMap<String,Integer> map1, map2, map3;
Then you can use Java 8 streams:
然后你可以使用 Java 8 流:
List<Map<String,Integer>> mapList = Arrays.asList(map1, map2, map3);
Map<String,Integer> combinedMap = mapList.stream()
.flatMap(map -> map.entrySet().stream())
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.summingInt(Entry::getValue)));