背景
有两个Map m1 m2,都是嵌套多层的,希望将m2合并到m1,合并的方式是
- m1做主表,m1有的key不能丢
- m2做副表,m2值不是对象类型(Map)时,把值直接覆盖到m1
- m2做副表,m2值是对象类型(Map)时,需要展开考虑m2的每个key,展开的每个key遵循以上两步更新给m1
例子
m1 = {a=1, b={x={i=1, y=1}, y=y, z=z}}
m2 = {b={x={i=11}}, c=3}
#合并后
m1 = {a=1, b={x={i=11, y=1}, y=y, z=z}, c=3}
上代码
public class mapTest3 {
public static void main(String[] args) {
Map<String, Object> m1 = new HashMap<>();
Map<String, Object> m2 = new HashMap<>();
Map<String, Object> x1 = new HashMap<>();
x1.put("i", 1);
x1.put("y", 1);
Map<String, Object> o1 = new HashMap<>();
o1.put("x", x1);
o1.put("y", "y");
o1.put("z", "z");
m1.put("a", 1);
m1.put("b", o1);
Map<String, Object> x2 = new HashMap<>();
x2.put("i", 11);
Map<String, Object> o2 = new HashMap<>();
o2.put("x", x2);
m2.put("b", o2);
m2.put("c", 3);
System.out.println(m1);
System.out.println(m2);
//m2第一层的key有m1没有,就直接覆盖,不用计算了
for (Map.Entry<String, Object> node2 : m2.entrySet()) {
Object x = m1.get(node2.getKey());
if (x == null) {
m1.put(node2.getKey(), m2.get(node2.getKey()));
}
}
loopMap(m1, null, m2);
System.out.println(m1);
}
public static void loopMap(Map<String, Object> m1, String p, Map<String, Object> m2) {
for (Map.Entry<String, Object> node : m1.entrySet()) {
if (node.getValue().getClass() == HashMap.class) {
String path;
if (p == null) {
path = node.getKey();
} else {
path = p + "." + node.getKey();
}
if(((HashMap) node.getValue()).size()==0){
Object result = getMapByPath(m2, path);
if(result!=null){
m1.put(node.getKey(),result);
}
}else {
loopMap((Map<String, Object>) node.getValue(), path, m2);
}
} else {
if (p != null) {
String path = p + "." + node.getKey();
Object result = getMapByPath(m2, path);
if (result != null) {
m1.put(node.getKey(), result);
}
}
}
}
}
public static Object getMapByPath(Map<String, Object> m2, String path) {
int point = path.indexOf(".");
if (point == -1) {
Object r = m2.get(path);
return r;
}
String key = path.substring(0, point);
String last = path.substring(point + 1, path.length());
Object result = m2.get(key);
if (result == null) {
return null;
} else {
try {
return getMapByPath((Map<String, Object>) result, last);
} catch (Exception e) {
return null;
}
}
}
}