使用流将地图结构中的地图展平

时间:2019-01-30 16:50:48

标签: java java-stream

我在HashMaps中具有以下结构(并非所有值都是地图(请参见id),并且嵌入了更多级别):

{ 
  "id":"0",
  "name":{  
      "title":"Mr.",
      "personName": {
          "firstName":"Boot",
          "familyName":"Strap"
      }
   }
}

我可以用Java 8流将其压扁吗

{ 
  "id":"0",
  "name.title":"Mr.",
  "name.personName.firstName":"Boot",
  "name.personName.familyName":"Strap"
}

2 个答案:

答案 0 :(得分:0)

Streams不会进行递归计算,您可以使用经典方式

static Map<String, String> flatten(Map<String, Object> map, String prefix) {
    prefix = prefix.isEmpty() ? prefix : prefix + ".";
    Map<String, String> res = new HashMap<>();
    for (Map.Entry<String, Object> entry : map.entrySet()) {
        if (entry.getValue() instanceof Map) {
            res.putAll(flatten((Map) entry.getValue(), prefix + entry.getKey()));
        } else {
            res.put(prefix + entry.getKey(), entry.getValue().toString());
        }
    }
    return res;
}

流方式看起来像

static Map<String, String> flatten(Map<String, Object> map, String p) {
    final String prefix = p.isEmpty() ? p : p + ".";
    return map.entrySet()
              .stream()
              .map(e -> {
                  if (e.getValue() instanceof Map) {
                      return (Set<Map.Entry<String, String>>) flatten((Map) e.getValue(), prefix + e.getKey()).entrySet();
                  } else {
                      return Map.of(prefix + e.getKey(), e.getValue().toString()).entrySet();
                  }
              })
              .flatMap(Set::stream)
              .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

并用作

public static void main(String[] args) {
    Map<String, Object> map = Map.of("id", 0, "name", Map.of("title", "Mr.", "personName", Map.of("firstName", "Boot", "familyName", "Strap")));
    Map<String, String> res = flatten(map, "");
    res.entrySet().forEach(System.out::println);
}

name.title=Mr.
name.personName.familyName=Strap
name.personName.firstName=Boot
id=0

答案 1 :(得分:0)

不使用eb deploy -m "deploy to stage" eb deploy -m "deploy to production" 很简单,但是使用递归:

Streams

PS 我知道循环中的字符串连接不好(最好使用public static Map<String, String> flatten(Map<String, Object> map) { return flatten("", map, new LinkedHashMap<>()); } private static Map<String, String> flatten(String parent, Map<String, Object> map, Map<String, String> res) { for (Map.Entry<String, Object> entry : map.entrySet()) { String key = parent.isEmpty() ? entry.getKey() : parent + '.' + entry.getKey(); if (entry.getValue() instanceof Map) flatten(key, (Map<String, Object>)entry.getValue(), res); else res.put(key, String.valueOf(entry.getValue())); } return res; } 甚至是StringBuilder),但是我使用Deque使这个例子更清楚。