java - 收集器嵌套分组,具有多个字段
问题描述
您将如何使用收集器在第二级按多个字段进行分组。例如:
"someList": {
"firstLevelElementX": {
"secondLevelElementW": 2,
"secondLevelElementZ": 3,
"secondLevelElementK": 7
},
"firstLevelElementY": {
"secondLevelElementW": 1,
"secondLevelElementZ": 3,
"secondLevelElementK": 10
}
}
我试图用“secondLevel”元素创建一个类,并按这个类分组,但无法使其工作:
@Data
@AllArgsConstructor
public class someClass{
private String firstLevelElement;
private Long secondLevelElementW;
private Long secondLevelElementZ;
private Long secondLevelElementK= 0L;
}
这就是我的做法:
Map<String,Map<String,Long>> someList =
events.stream().collect(
Collectors.groupingBy(
someDAO::getFirstLevelElement,
Collectors.groupingBy(
someClass::getSecondLevelFields,
Collectors.counting())
)
);
有一些解决方案建议使用 n 级分组(使用链),但如果可能的话,我更喜欢让它不那么复杂和更干净。
编辑
我将尝试提供一个更好的示例以澄清自己,这是我拥有的列表:
{
"date": "2019-04-08 08:28:01.0",
"source": "maint",
"severity": "HARMLESS",
"site": "USA",
"hostname": "usaHost"
},
{
"date": "2019-04-08 08:28:01.0",
"source": "CPU_Checker",
"severity": "MINOR",
"site": "GERMANY",
"hostname": "germanyHost"
},
{
"date": "2019-04-02 08:28:01.0",
"source": "maint",
"severity": "HARMLESS",
"site": "USA",
"hostname": "anotherUsaHost"
}
我想在第二级的“源”和“严重性”上使用分组,所以输出应该是这样的:
"eventList": {
"USA": {
"maint": 2,
"HARMLESS": 2
},
"GERMANY": {
"CPU_checker": 1,
"MINOR": 1
}
}
解决方案
如果您可以使用Java 9或更高版本,则可以使用Collectors.flatMapping()
来实现:
Map<String, Map<String, Long>> eventList = list.stream()
.collect(Collectors.groupingBy(MyObject::getSite, Collectors.flatMapping(
o -> Stream.of(o.getSource(), o.getSeverity()),
Collectors.groupingBy(Function.identity(), Collectors.counting())
)));
结果将是这样的:
{
USA={maint=2, HARMLESS=2},
GERMANY={CPU_Checker=1, MINOR=1}
}
如果您不能使用Java 9,您可以自己实现该flatMapping()
功能。您可以查看用 Java 8 重写的 Java 9 Collectors.flatMapping,它应该对您有所帮助。
推荐阅读
- java - 设置 Spring Native Experimental(在以下任何来源中均未找到 id 'org.springframework.experimental.aot' 版本 '0.10.3')
- java - 如何在不删除任何潜在重复项的情况下从字符串中删除参数?
- flutter - Flutter Moor 插入阵列
- python - 如何使用 Python 同时从服务器获取多个数据?
- xml - 在火花中读取 xml 文件时从 xml 属性中提取值
- java - Junit Jupiter 5.8.x ClassOrder
- excel - 用 VBA 将月份除以周数
- streaming - 以编程方式将视频从内置 wifi ip 摄像头流式传输到 android 设备
- mongodb - 如何为 mongodb 编写相关的 $lookup 查询?
- google-sheets - 谷歌数据工作室案例当两组标准