Java 在 innermost/leaf 级别合并嵌套的 HashMap
Java Merge Nested HashMaps at the innermost/leaf level
假设我有 2 个键值对:
String k1 = "a.b.c.d";
String v1 = "123";
String k2 = "a.b.c.d";
String v2 = "456";
所需的输出是:
a {
b {
c {
d = "123",
e = "456"
}
}
}
所以,我决定用“.”分割键。并形成嵌套的 HashMap,然后在它们具有重复键时尝试合并它们。但是,它需要在叶子或最内层而不是最外层合并。
这是完整代码:
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestClass {
public static void main(String []args)
{
Map<String, Object> finalMap = new HashMap<>();
Map<String, Object> outerMap1 = new HashMap<>();
Map<String, Object> outerMap2 = new HashMap<>();
String k = "a.b.c.d";
String v = "123";
outerMap1 = createNestedStructure(k, v);
k = "a.b.c.e";
v = "456";
outerMap2 = createNestedStructure(k, v);
finalMap = Stream
.concat(outerMap1.entrySet().stream(),
outerMap2.entrySet().stream())
.collect(Collectors.toMap(Entry::getKey,
Entry::getValue, (a, b) -> {
String c = a.toString() + "\n" + b.toString();
return c;
}, HashMap::new));
System.out.println(finalMap.toString());
}
public static Map<String, Object> createNestedStructure(String k, String v)
{
String[] tokens = k.split("\.");
Map<String, String> innerMap = new HashMap<>();
v = "\"" + v + "\"";
innerMap.put(tokens[tokens.length-1], v);
Map<String, Object> middleMap = new HashMap<>();
middleMap.put(tokens[tokens.length-2], innerMap);
for(int i=tokens.length-3; i>=0; i--)
{
Map<String, Object> middleMapTmp = new HashMap<>();
middleMapTmp.put(tokens[i], middleMap);
middleMap = middleMapTmp;
}
// Map<String, Object> outerMap = new HashMap<>();
// outerMap.put(tokens[0], middleMap);
// return outerMap;
return middleMap;
}
}
我不确定这是否是正确的方法。因此,也欢迎提出更好的方法建议。
不确定您的具体问题,但您可以简单地将这些值插入到相同的结构中,而不是事后合并它们。例如,您可以进行递归插入以创建嵌套映射,直到它在最后一个键部分插入您的值。如果嵌套地图已经存在,它会使用现有的地图。像这样的东西可以解决问题:
public static void main(String[] args) {
String k1 = "a.b.c.d";
String v1 = "123";
String k2 = "a.b.c.e";
String v2 = "456";
Map<String, Object> map = new HashMap<>();
recursiveInsert(map,k1, v1);
recursiveInsert(map,k2, v2);
System.out.println(map);
}
public static void recursiveInsert(Map<String, Object> map, String key, String value) {
int index = key.indexOf('.');
if (index == -1) {
map.put(key, value);
} else {
String subKey = key.substring(0, index);
map.putIfAbsent(subKey, new HashMap<>());
recursiveInsert((Map<String, Object>) map.get(subKey), key.substring(index + 1), value);
}
}
这就是您要求的输出:
{a={b={c={d=123, e=456}}}}
假设我有 2 个键值对:
String k1 = "a.b.c.d";
String v1 = "123";
String k2 = "a.b.c.d";
String v2 = "456";
所需的输出是:
a {
b {
c {
d = "123",
e = "456"
}
}
}
所以,我决定用“.”分割键。并形成嵌套的 HashMap,然后在它们具有重复键时尝试合并它们。但是,它需要在叶子或最内层而不是最外层合并。
这是完整代码:
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestClass {
public static void main(String []args)
{
Map<String, Object> finalMap = new HashMap<>();
Map<String, Object> outerMap1 = new HashMap<>();
Map<String, Object> outerMap2 = new HashMap<>();
String k = "a.b.c.d";
String v = "123";
outerMap1 = createNestedStructure(k, v);
k = "a.b.c.e";
v = "456";
outerMap2 = createNestedStructure(k, v);
finalMap = Stream
.concat(outerMap1.entrySet().stream(),
outerMap2.entrySet().stream())
.collect(Collectors.toMap(Entry::getKey,
Entry::getValue, (a, b) -> {
String c = a.toString() + "\n" + b.toString();
return c;
}, HashMap::new));
System.out.println(finalMap.toString());
}
public static Map<String, Object> createNestedStructure(String k, String v)
{
String[] tokens = k.split("\.");
Map<String, String> innerMap = new HashMap<>();
v = "\"" + v + "\"";
innerMap.put(tokens[tokens.length-1], v);
Map<String, Object> middleMap = new HashMap<>();
middleMap.put(tokens[tokens.length-2], innerMap);
for(int i=tokens.length-3; i>=0; i--)
{
Map<String, Object> middleMapTmp = new HashMap<>();
middleMapTmp.put(tokens[i], middleMap);
middleMap = middleMapTmp;
}
// Map<String, Object> outerMap = new HashMap<>();
// outerMap.put(tokens[0], middleMap);
// return outerMap;
return middleMap;
}
}
我不确定这是否是正确的方法。因此,也欢迎提出更好的方法建议。
不确定您的具体问题,但您可以简单地将这些值插入到相同的结构中,而不是事后合并它们。例如,您可以进行递归插入以创建嵌套映射,直到它在最后一个键部分插入您的值。如果嵌套地图已经存在,它会使用现有的地图。像这样的东西可以解决问题:
public static void main(String[] args) {
String k1 = "a.b.c.d";
String v1 = "123";
String k2 = "a.b.c.e";
String v2 = "456";
Map<String, Object> map = new HashMap<>();
recursiveInsert(map,k1, v1);
recursiveInsert(map,k2, v2);
System.out.println(map);
}
public static void recursiveInsert(Map<String, Object> map, String key, String value) {
int index = key.indexOf('.');
if (index == -1) {
map.put(key, value);
} else {
String subKey = key.substring(0, index);
map.putIfAbsent(subKey, new HashMap<>());
recursiveInsert((Map<String, Object>) map.get(subKey), key.substring(index + 1), value);
}
}
这就是您要求的输出:
{a={b={c={d=123, e=456}}}}