根据key将Map<String,String>扩展为Map<String,Map>

Expanding a Map<String,String> to Map<String,Map> based on the key

如果我有这样的地图:

Map.of("key1", "value1",
       "key2.subkey1", "subvalue1",
       "key2.subkey2", "subvalue2",
       "key2.subkey3.subsubkey", "subsubvalue");

然后我想将它转换成这样的(可能)地图的地图:

Map.of("key1", "value1",
       "key2", Map.of("subkey1", "subvalue1",
                      "subkey2", "subvalue2",
                      "subkey3", Map.of("subsubkey", "subsubvalue)));

我想我需要像这样拆分密钥:

entry.getKey().split("\.", 2);

但我想不出在那之后该做什么。

我已经设法使这个方法达到了我想要的效果,但它看起来不太漂亮:(

private Map<String, Object> expandMap(Map<String, String> oldMap) {
    HashMap<String, Object> newMap = new HashMap<>();
    oldMap.forEach((key, value) -> {
        String[] keys = key.split("\.", 2);
        if (keys.length == 1) {
            newMap.put(keys[0], value);
        } else {
            newMap.merge(keys[0], expandMap(Map.of(keys[1], value)), (obj1, obj2) -> {
                if (obj1 instanceof Map && obj2 instanceof Map) {
                    Map<String, Object> map1 = (Map<String, Object>) obj1;
                    Map<String, Object> map2 = (Map<String, Object>) obj2;
                    return Stream.concat(map1.entrySet().stream(), map2.entrySet().stream()).collect(toMap(Entry::getKey, Entry::getValue));
                }
                return null;
            });
        }
    });
    return newMap;
}

欢迎您分享您的想法。

我喜欢在这些情况下使用递归(级联键):

public static Map<String, Object> covert(Map<String, String> map) {
    Map<String, Object> result = new HashMap<>();
    map.forEach((key, value) -> parseAndPut(result, key, value));
    return result;
}

@SuppressWarnings("unchecked")
private static void parseAndPut(Map<String, Object> map, String key, String value) {
    String[] keys = key.split("\.");
    if (keys.length == 1) {
        map.put(key, value);
    } else if (keys.length > 1) {
        String subKey = keys[0];
        Map<String, Object> valueMap = (Map<String, Object>) map.computeIfAbsent(subKey, s -> new HashMap<>());
        int beginIndex = key.indexOf(subKey) + subKey.length() + 1;
        parseAndPut(valueMap, key.substring(beginIndex), value);
    }
}

输入数据的输出:

{key1=value1, key2={subkey1=subvalue1, subkey2=subvalue2, subkey3={subsubkey=subsubvalue}}}