繁体   English   中英

将 map 转换为嵌套 map

[英]Convert map to nested map

我的 YamlFile class 上有这个 map,它以这种格式存储文件的所有键:String key = "firskey.secondkey.thirdkey", Z497031794414A552435F90151AC3B54B value = "Example value"

  private static Map<String, Object> deepkeymap;

现在,我想将我的 deepkeymap 转换为嵌套的 map,其工作原理如下:{firstkey={secondkey={thirdkey="Example value"}}},我的 deepkeymap 实际上存储了 4 个具有 4 个值的键(键和值的数量将改变)。 我已经完成了这一点,但并不完全因为它只转换我的 deepkeymap 的最后一个键和值,事实上,我放的例子是我的嵌套 map 的 output,这里是代码:

public void save() {
    try {
        Map<String, Object> datamap = new HashMap<String, Object>();
        for(String key : deepkeymap.keySet()) {
            Object value = deepkeymap.get(key);
            int end = key.length();
            for(int start; (start = key.lastIndexOf('.', end - 1)) != -1; end = start) {
                value = new HashMap<>(Collections.singletonMap(key.substring(start + 1, end), value));
            }
            datamap.putAll(new HashMap<>(Collections.singletonMap(key.substring(0, end), value)));
        }
        System.out.println("Datamap: "+datamap);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

如上所述,output 为:

Datamap: {firstkey={secondkey={thirdkey="Example value"}}}

但它应该还有另外 3 个键,因为 deepkeymap 包含 4 个键和它们各自的 4 个值,我已经检查过它们存储在上面,没有人有 null 值,对 keySet 循环打印键和值进行调试。

您可以使用下面的代码。 工厂方法因输入错误而失败,而且DeepKeyMap只有toString。 下面是一个 JUnit 测试,它只是运行代码并且什么都不测试。 如果您将来使用它,您可以将 DeepKeyMap 提取到单独的 class 中。

public class MapTest
{
    static class DeepKeyMap
    {
        Map<String, Object> map = new HashMap<>();

        public void put(
                String path,
                Object value
        )
        {
            String[] split = path.split("\\.");

            this.put(split, value);
        }

        public void put(
                String[] path,
                Object value
        )
        {
            Map<String, Object> deepestMap = createMapsToTheDeepestKey(path);
            String deepestKey = path[path.length - 1];

            deepestMap.put(deepestKey, value);
        }

        private Map<String, Object> createMapsToTheDeepestKey(String[] path)
        {
            Map<String, Object> deepestMap = map;

            for (int i = 0; i < path.length - 1; i++)
            {
                String key = path[i];
                deepestMap = getDeeperMap(deepestMap, key);
            }

            return deepestMap;
        }

        private Map<String, Object> getDeeperMap(
                Map<String, Object> deepestMap,
                String key
        )
        {
            if (!deepestMap.containsKey(key))
            {
                deepestMap.put(key, new HashMap<>());
            }

            return (Map<String, Object>) deepestMap.get(key);
        }

        @Override
        public String toString()
        {
            return map.toString();
        }

        public static DeepKeyMap from(Map<String, Object> original)
        {
            DeepKeyMap result = new DeepKeyMap();

            // the for loop can be minimized to
            // original.forEach(result::put);
            for (var entry : original.entrySet())
            {
                result.put(entry.getKey(), entry.getValue());
            }

            return result;
        }
    }

    @Test
    void test()
    {
        Map<String, Object> original = Map.of("flat", "First Level",
                "nested.value.one", "Second Level",
                "nested.value.two", "Third Level",
                "nested.different.value.one", "Fourth Level"
        );

        DeepKeyMap deepMap = DeepKeyMap.from(original);

        System.out.println(deepMap);
    }
}

编辑:我重构了上面的代码。 希望它更清楚它的作用。

我不会那样使用它,您可以在不同级别上使用相同的键,这不是 Map 的意图。

此外,您可以生成一个构造,其键类型为 map 或字符串。 这带来了各种不确定性。

您应该考虑使用其他数据结构或数据库。

您的意图是什么,也许我们可以为您提供帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM