java - Java8 - 如何将嵌套映射转换为按内部映射键值收集的嵌套映射列表
问题描述
我有一个嵌套的地图对象,如下所示
{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()
with 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}}
]
推荐阅读
- node.js - DynamoDB sql 查询扫描以获取日期时间范围计数
- macos - dnsmasq - Apple Silicon M1 上的服务状态问题
- excel - 基于多个单元格值隐藏/取消隐藏行
- javascript - typeError:无法读取未定义的属性“PROVIDER_ID”我正在使用最新的 SDK
- r - 删除重复行并更改 R 中数据框中的值
- dpdk - 如何禁用 RSS 但仍在 DPDK 中使用多个 RX 队列?
- flutter - Flutter 中的 ReactJS 子代等价物
- ruby-on-rails - 从不同域发送电子邮件
- bootstrap-4 - 列没有在移动视图或小屏幕中调整,它们正在引导程序 4 中移动到下一行
- visual-studio-code - 如何在 VSCode 中更改编辑器缩进的颜色