用 Java 8 合并两张地图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/40158605/
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
Merge two maps with Java 8
提问by dardy
I have two maps like this:
我有两张这样的地图:
map1 = new Map<String, MyObject>();
map2 = new Map<String, MyObject>();
MyObject {
Integer mark1;
Integer mark2;
}
What I want to do to is to merge the two maps into a map3
<String, MyObject>
like this:
我想要做的是将两张地图合并成一个map3
<String, MyObject>
这样的:
- If
map1.place
is not inmap2.place
, then I add the entry tomap3
. - same if
map2.place
is not inmap1.place
, I add the entry tomap3
. - if
map1.place
is inmap2.place
, then I add this entry:map1.place, (map1.mark1, map2.mark2)
- 如果
map1.place
不在 中map2.place
,那么我将条目添加到map3
. - 如果
map2.place
不在 中map1.place
,我将条目添加到map3
. - 如果
map1.place
在map2.place
,那么我添加这个条目:map1.place, (map1.mark1, map2.mark2)
I have read about flatMap
, but I really have a hard time using it.
Any clue how to do this?
Thanks!!
我读过关于flatMap
,但我真的很难使用它。任何线索如何做到这一点?
谢谢!!
采纳答案by Ash
Here is what I think would work
这是我认为可行的方法
Map<String, MyObj> map3 = new HashMap<>(map1);
map2.forEach(
(key, value) -> map3.merge(key, value, (v1, v2) -> new MyObject(v1.mark1,v2.mark2))
);
The merge function is what is taking care of your scenario 3, in that if the key already exists, it creates a new MyObject with v1.mark1 and v2.mark2
合并函数负责处理您的场景 3,因为如果键已经存在,它会创建一个带有 v1.mark1 和 v2.mark2 的新 MyObject
回答by talex
Something like this should work.
像这样的事情应该有效。
Map<String, MyObject> result = new HashMap<String, MyObject>();
Set<String> allKeys = new HashSet<String>();
allKeys.addAll(map1.keySet());
allKeys.addAll(map2.keySet());
for(String key : allKeys){
MyObject v1 = map1.get(key);
MyObject v2 = map2.get(key);
if(v1 != null && v2 == null){
result.put(key, v1);
}else if(v1 == null && v2 !=null){
result.put(key, v2);
} else {
MyObject newObject = new MyObject(v1.mark1, v2.mark2);
result.put(key, newObject);
}
}
回答by Jerin Joseph
Incase of a simple merge you could use map3.putAll()
as explained in How can I combine two HashMap objects containing the same types?
如果您可以使用简单的合并,map3.putAll()
如如何组合包含相同类型的两个 HashMap 对象中所述?
In your case, you would probably have to write some custom logic,
在您的情况下,您可能需要编写一些自定义逻辑,
First populate map3 with map1. Then Iterate the map3 to find any duplicates with map2 in which case you replace the entry with the map1.place, (map1.mark1, map2.mark2)
logic.
首先用 map1 填充 map3。然后迭代 map3 以使用 map2 查找任何重复项,在这种情况下,您将条目替换为map1.place, (map1.mark1, map2.mark2)
逻辑。
MapMerge
地图合并
public class MapMerge {
public static void main(String []args){
Map<String, MyObject> map1 = new HashMap<String, MyObject>();
Map<String, MyObject> map2 = new HashMap<String, MyObject>();
Map<String, MyObject> map3 = new HashMap<String, MyObject>();
map3.putAll(map1);
for(Entry<String, MyObject> entry:map2.entrySet()){
if (map3.containsKey(entry.getKey())){
MyObject map3Obj = map3.get(entry.getKey());
map3.put(
entry.getKey(),
new MyObject(map3Obj.getMark1(),entry.getValue().getMark2())
);
}
}
}
}
MyObject
我的对象
class MyObject{
public MyObject(Integer m1, Integer m2){
mark1 = m1;
mark2 = m2;
}
public Integer getMark1() {
return mark1;
}
public void setMark1(Integer mark1) {
this.mark1 = mark1;
}
public Integer getMark2() {
return mark2;
}
public void setMark2(Integer mark2) {
this.mark2 = mark2;
}
Integer mark1;
Integer mark2;
}
回答by Nicolas Filotto
It can be done using the Stream API
with the appropriate mergeFunction
as next:
可以使用Stream API
适当的方法来完成,mergeFunction
如下所示:
Map<String, MyObject> map3 = Stream.of(map1, map2)
.flatMap(map -> map.entrySet().stream())
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> new MyObject(v1.getMark1(), v2.getMark2())
)
);
This concatenates entries of map1
followed by the entries of map2
, then convert everything as a Map
with a merge function that will use mark1
from the first value (the one from map1
) and mark2
from the second value (the one from map2
) in case of duplicate keys.
这连接了 的条目,map1
然后是 的条目map2
,然后Map
使用合并函数将所有内容转换为 a ,该函数将使用mark1
第一个值(来自 的值map1
)和 mark2
第二个值(来自 的值map2
),以防出现重复键。
Or it could also be done using a different Supplier<Map>
that will propose a map that already contains the entries of map1
then we can focus only on adding the entries of map2
as next:
或者也可以使用不同的方法来完成Supplier<Map>
,它会提出一个已经包含条目的映射,map1
那么我们可以只专注于添加如下条目map2
:
Map<String, MyObject> map3 = map2.entrySet()
.stream()
.collect(
Collectors.toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(v1, v2) -> new MyObject(v1.getMark1(), v2.getMark2()),
() -> new HashMap<>(map1)
)
);
回答by Soudipta Dutta
Case 1: Given a List of Maps. Then Join the maps according to the Key
案例 1:给定地图列表。然后根据Key加入地图
public class Test14 {
public static void main(String[] args) {
Map<String, List<Integer>> m1 = new HashMap<>();
Map<String, List<Integer>> m2 = new HashMap<>();
m1.put("a", List.of(1));
m1.put("b", List.of(2, 3));
m2.put("a", List.of(12, 115));
m2.put("b", List.of(2, 5));
m2.put("c", List.of(6));
System.out.println("map1 => " + m1);
System.out.println("map2 => " + m2);
ArrayList<Map<String, List<Integer>>> maplist = new ArrayList<Map<String, List<Integer>>>();
maplist.add(m1);
// map1 => {a=[1], b=[2, 3]}
maplist.add(m2);
// map2 => {a=[12, 115], b=[2, 5], c=[6]}
System.out.println("maplist => " + maplist);
// maplist => [{a=[1], b=[2, 3]}, {a=[12, 115], b=[2, 5], c=[6]}]
// flatmap does omitted {}
List<Entry<String, List<Integer>>> collect11 =
maplist
.stream()
.flatMap(map -> map.entrySet().stream())
.collect(Collectors.toList());
System.out.println(" collect11 => " + collect11);
// collect11 => [a=[1], b=[2, 3], a=[12, 115], b=[2, 5], c=[6]]
// That's why we will use this flatmap
Map<String, List<Integer>> map2 = maplist.stream()
.flatMap(map -> map.entrySet().stream())
.collect(
Collectors.toMap(
//keyMapper
Map.Entry::getKey,
//valueMapper
Map.Entry::getValue,
(list_a,list_b) -> Stream.concat(list_a.stream(), list_b.stream())
.collect(Collectors.toList())
)//tomap
);
//{a=[1, 12, 115], b=[2, 3, 2, 5], c=[6]}
System.out.println("After joining the maps according the key => " + map2);
// After joining the maps according the key => {a=[1, 12, 115], b=[2, 3, 2, 5], c=[6]}
/*
OUTPUT :
After joining the maps according the key => {a=[1, 12, 115], b=[2, 3, 2, 5], c=[6]}
*/
}// main
}