Java 在最内/叶级别合并嵌套 HashMap

发布于 2025-01-13 17:02:59 字数 2310 浏览 1 评论 0原文

假设我有 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;
   }
}

我不确定这是否是正确的方法。因此,也欢迎提出更好方法的建议。

Say I got 2 Key Value pairs:

String k1 = "a.b.c.d";
String v1 = "123";
String k2 = "a.b.c.d";
String v2 = "456";

And the desired output is:

a {
  b {
    c {
      d = "123",
      e = "456"
    }
  }
}

So, I've decided the split the keys by "." and form nested HashMaps and then trying to merge them when they have duplicate keys. However, it needs to merge at the leaf or innermost level instead of the outermost level.

This is the full code:

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

I'm not sure if this is the correct approach. So suggestions on better approaches are also welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冰葑 2025-01-20 17:03:00

不太确定您的具体问题,但您可以简单地将值插入到同一结构中,而不是随后合并它们。例如,您可以进行递归插入,创建嵌套映射,直到将您的值插入最后一个关键部分。如果嵌套映射已经存在,它将使用现有的映射。像这样的东西可以解决这个问题:

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

Not exactly sure about your specific problem, but you could simply insert the values into the same structure instead of merging them afterward. For example, you can make a recursive insert that creates the nested maps until it inserts your value on the last key part. If the nested map already exists it uses the existing one. Something like this could do the trick:

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

The output of this is what you requested:

{a={b={c={d=123, e=456}}}}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文