繁体   English   中英

Java8-如何将嵌套地图转换为通过内部地图的键值收集的嵌套地图列表

[英]Java8 - How to convert a nested maps to list of nested maps gathered by value of inner map's key

我有一个嵌套的地图对象,如下所示

{12345={{"status":"200","outcome":"Success","message":"Account created"}}
{23121={{"status":"400","outcome":"Exception","message":"Invalid State value"}}
{43563={{"status":"200","outcome":"Success","message":"Account updated"}}
{72493={{"status":"400","outcome":"Exception","message":"Bad Request"}}

我需要将其转换为Map<String, List<Map<String, Map<String, String>>> ,其中外部地图的键是状态的值( 200 or 400 ) ,而值是原始地图的列表状态= 200或400或内部地图中的其他有效值。

因此,新结构看起来像

{{200={[{12345={"status":"200","outcome":"Success","message":"Account created"}},
       {43563={"status":"200","outcome":"Success","message":"Account updated"}}
      ]
     },
{400={[{23121={"status":"400","outcome":"Exception","message":"Invalid State value"}},
       {72493={"status":"400","outcome":"Exception","message":"Bad Request"}}
      ]
     }
}

最终,我需要根据不同的状态生成报告。

这是我开始时遇到的问题,但仍然存在。

我想遍历外部地图,获取内部地图,获取状态键的值,然后根据状态码值将地图添加到列表中。

这就是我使用循环的方式

private static Map<String, List<Map<String, Map<String, String>>>> covertToReport(Map<String, Map<String, String>> originalMap) {
    Map<String, List<Map<String, Map<String, String>>>> statusBasedListOfMaps = new TreeMap<>();
    //loop through the map
    //for each key, get the inner map
    //get the status value for each inner map

    List<Map<String, Map<String, String>>> accountsMapsList;
    for (Entry<String, Map<String, String>> entry : originalMap.entrySet()) {
        String accNum = entry.getKey();
        Map<String, String> childMap = entry.getValue();
        String stausVal = childMap.get("status");
        accountsMapsList = statusBasedListOfMaps.get(stausVal) == null ? new ArrayList<>() : statusBasedListOfMaps.get(stausVal);
        accountsMapsList.add((Map<String, Map<String, String>>) entry);
        statusBasedListOfMaps.put(stausVal, accountsMapsList);
    }
    return statusBasedListOfMaps;
}

当然,下面的代码不会编译,但这就是我想要得到的。

private static void covertToReport(Map<String, Map<String, String>> originalMap) {
    Map<String, List<Map<String, Map<String, String>>>> statusBasedListOfMaps;

    statusBasedListOfMaps = originalMap.entrySet()
       .stream()
       .filter(e -> e.getValue()
          .values()
          .stream()
          .map(innerMap -> Collectors.toList())
       .collect(Collectors.toMap(Map.Entry::getKey, Collectors.toList(e)));

这可能吗?

您可以仅将Collectors.groupingBy()Collectors.mapping()

private static Map<String, List<Map<String, Map<String, String>>>> convertToReport(Map<String, Map<String, String>> originalMap) {
    return originalMap.entrySet().stream()
            .collect(Collectors.groupingBy(e -> e.getValue().get("status"), 
                    Collectors.mapping(Map::ofEntries, Collectors.toList())));
}

您可以按status分组,然后使用Map.ofEntries()将关联的条目映射到自己的地图。 如果您使用的是Java,则可以使用它代替Map::ofEntries

e -> new HashMap<>() {{ put(e.getKey(), e.getValue()); }}

结果将是这样的:

200=[
    {12345={status=200, message=Account created, outcome=Success}}, 
    {43563={status=200, message=Account created, outcome=Success}}
],
400=[
    {72493={status=400, message=Invalid State value, outcome=Exception}}, 
    {23121={status=400, message=Invalid State value, outcome=Exception}}
]

您的函数返回一个Map<String, List<Map<String, Map<String, String>>>> ,但是您的结构看起来像Map<String, Map<String, Map<String, String>>>

如果您真正想要的是Map<String, Map<String, Map<String, String>>>是代码: Map<String, Map<String, Map<String, String>>> result= map.entrySet().stream().collect(Collectors.groupingBy(entry -> entry.getValue().get("status"), Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)));

暂无
暂无

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

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