使用 Stream 展平嵌套的 Hashmap

Flattening a nested Hashmap using Stream

我有一个嵌套的 HashMap<String,Object>,我想通过展平 Hashmap 创建一个 HashMap<String,String>。我试过 的解决方案。但是我无法使用答案中提到的 class FlatMap

我也尝试了问题本身的解决方案,但我仍然遗漏了一些东西。然后我找到了一个类似的用例并提出了以下解决方案。但似乎我缺少一些作为 lambda 函数 flatMap 参数的东西。

public static void main(String[] args) {
  Map<String,Object> stringObjectMap= new HashMap<String,Object>();
  stringObjectMap.put("key1","value1");
  stringObjectMap.put("key2","value2");
  Map<String,Object> innerStringObjectMap = new HashMap<>();
  innerStringObjectMap.put("i1key3","value3");
  innerStringObjectMap.put("i1key4","value4");
  innerStringObjectMap.put("i1key5","value5");
  stringObjectMap.put("map1",innerStringObjectMap);
  Map<String,Object> innerStringObjectMap2 = new HashMap<>();
  innerStringObjectMap.put("i2key6","value6");
  innerStringObjectMap2.put("i2key7","value7");
  innerStringObjectMap.put("i1map2",innerStringObjectMap2);

  Map<String,Object> collect =
        stringObjectMap.entrySet().stream()
                .map(x -> x.getValue())
                .flatMap(x -> x) //I aint sure what should be give here
                .distinct(); //there was a collect as List which i removed.

  //collect.forEach(x -> System.out.println(x));

}

展平嵌套地图的更好解决方案是什么?我不仅对值感兴趣,还对地图中的键感兴趣。这就是我决定将地图展平以获得另一张地图的原因(我不确定这是否可能)

编辑 - 预期输出

key1 - value1
key2-value2
map1 =""  //this is something i will get later for my purpose
i1key3=value3
.
.
i1map2=""
.
.
i2key7=value7

我根据您的需要从修改了class:

public class FlatMap {

  public static Stream<Map.Entry<?, ?>> flatten(Map.Entry<?, ?> e) {
    if (e.getValue() instanceof Map<?, ?>) {
      return Stream.concat(Stream.of(new AbstractMap.SimpleEntry<>(e.getKey(), "")),
                           ((Map<?, ?>) e.getValue()).entrySet().stream().flatMap(FlatMap::flatten));
    }

    return Stream.of(e);
  }
}

用法:

Map<?, ?> collect = stringObjectMap.entrySet()
                                   .stream()
                                   .flatMap(FlatMap::flatten)
                                   .collect(Collectors.toMap(
                                       Map.Entry::getKey,
                                       Map.Entry::getValue,
                                       (u, v) -> throw new IllegalStateException(String.format("Duplicate key %s", u)),
                                       LinkedHashMap::new));

注意:
请务必使用提供的 collectLinkedHashMap,否则顺序将被搞砸。

我已经使用了 中的功能。但是我以不同的方式使用了这个函数。

Map<Object, Object> collect = new HashMap<>();
stringObjectMap.entrySet()
        .stream()
        .flatMap(FlatMap::flatten).forEach(it -> {
          collect.put(it.getKey(), it.getValue());
});

再次函数

public static Stream<Map.Entry<?, ?>> flatten(Map.Entry<?, ?> e) {
if (e.getValue() instanceof Map<?, ?>) {
  return Stream.concat(Stream.of(new AbstractMap.SimpleEntry<>(e.getKey(), "")),
          ((Map<?, ?>) e.getValue()).entrySet().stream().flatMap(FlatMap::flatten));
}

return Stream.of(e);
}