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}}}}