首页 > 解决方案 > 在 java 8 流中将映射转换为更扁平的结构

问题描述

我有以下代码:

private Map<String, Object> flatten(Map<String, Object> source) {
    Map<String, Object> result = new LinkedHashMap<>();

    source.forEach((k, v) -> {
        if (v instanceof Map) {
            Map<String, Object> subMap = flatten((Map<String, Object>) v);
            for (String subkey : subMap.keySet()) {
                result.put(k + "." + subkey, subMap.get(subkey));
            }
        } else result.put(k, v);
    });

    return result;
}

上面的代码展平了给定的地图

Ex: 
{
  "hello": {
    "hi": {
      "hola": 1
    }
  }
}

to 
{
  "hello.hi.hola": 1
}

我想使用 Java8 流并实现相同的逻辑,我该怎么做?

标签: javadictionaryrecursionjava-8java-stream

解决方案


不,Stream API 的设计并没有很好地适应递归。使用 Stream API 或重构来“增强”您的解决方案的可能性不大。从其包信息中 Stream API 的定义很明显,它们的使用必须是无干扰的无状态的且没有副作用- 因此我无法想象你将如何使用这个 API 来实现这一点。

我发现修改内部块的唯一可能用法if-condition并没有带来真正的好处:

if (v instanceof Map) {
    Map<String, Object> subMap = flatten((Map<String, Object>) v);
    subMap.keySet().stream().forEach(subkey -> result.put(k + "." + subkey, subMap.get(subkey)));
} else result.put(k, v);

推荐阅读