如何将 List<Map<String, String>> 转换为 Map<String, List<String>>

Dee*_*rma 1 java collections java-stream

我有地图列表List<Map<String,String>>并想转换成Map<String, List String>>

下面是示例代码

List<Map<String,String>> recordListMap = new ArrayList<>();

Map<String,String> recordMap_1 = new HashMap<>();
recordMap_1.put("inputA", "ValueA_1");
recordMap_1.put("inputB", "ValueB_1");
recordListMap.add(recordMap_1);

Map<String,String> recordMap_2 = new HashMap<>();
recordMap_2.put("inputA", "ValueA_2");
recordMap_2.put("inputB", "ValueB_2");
recordListMap.add(recordMap_2);
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法,但没有得到所需的结果:

Map<String, List<String>> myMaps = new HashMap<>();
for (Map<String, String> recordMap : recordListMap) {
    for (Map.Entry<String, String> map : recordMap.entrySet()) {
        myMaps.put(map.getKey(), List.of(map.getValue()));
    }
}
OutPut: {inputB=[ValueB_2], inputA=[ValueA_2]}
Run Code Online (Sandbox Code Playgroud)

预期结果:

{inputB=[ValueB_1, ValueB_2], inputA=[ValueA_1, ValueA_2]}
Run Code Online (Sandbox Code Playgroud)

WJS*_*WJS 6

像这样尝试一下。

  • computeIfAbsent如果键不存在,将添加列表作为键的值。
  • 返回列表new or existing,以便现在可以将对象添加到该列表中。
Map<String, List<String>> myMaps = new HashMap<>();
for (Map<String, String> map : recordListMap) {
    for (Entry<String, String> e : map.entrySet()) {
        myMaps.computeIfAbsent(e.getKey(), v -> new ArrayList<>())
                .add(e.getValue());
    }
}
myMaps.entrySet().forEach(System.out::println);
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用流。

  • 流式传输地图列表。
  • 然后流式传输每个映射的entrySet,将其展平为单个条目流。
  • 然后按键分组并将值放入列表中。
Map<String, List<String>> myMaps2 = recordListMap.stream()
        .flatMap(map -> map.entrySet().stream())
        .collect(Collectors.groupingBy(Entry::getKey, Collectors
                .mapping(Entry::getValue, Collectors.toList())));


Run Code Online (Sandbox Code Playgroud)

两者都将包含

inputB=[ValueB_1, ValueB_2]
inputA=[ValueA_1, ValueA_2]

Run Code Online (Sandbox Code Playgroud)

查看Map.computeIfAbsent