我有一个像这样的POJO:
class Employee {
String name;
String designation;
String address;
//Getters and setters
//All args constructor
}
我已经填充了此类对象的列表。
现在,我需要获取每个属性的每个值及其频率。
例如,如果我的列表是这样的:
List<Employee> list = List.of(
new Employee("Amit", "Manager", "Delhi"),
new Employee("Arun", "VP", "Agra"),
new Employee("Arun", "President", "Bangalore"),
new Employee("Rahul", "VP", "Delhi"),
new Employee("Amit", "Manager", "Agra")
);
然后我应该得到类似这样的结果(请注意,对于每个属性,其值都映射到其频率):
{
name = {Rahul = 1, Arun = 2, Amit = 2},
designation = {President = 1, VP = 2, Manager = 2},
address = {Delhi = 2, Bangalore = 1, Agra = 2}
}
下面给出的语句适用于当前数据(保证列表中任何对象的属性都不包含空值):
Map<String, Map<String, Long>> attributeFrequencies = list.stream()
.flatMap(e -> Map.of(
"name", e.getName(),
"designation", e.getDesignation(),
"address", e.getAddress()
).entrySet().stream())
.collect(Collectors.groupingBy(Map.Entry::getKey,
Collectors.groupingBy(Map.Entry::getValue, Collectors.counting())));
但是,如果我将原始列表更改为如下所示:
List<Employee> list = List.of(
new Employee("Amit", "Manager", "Delhi"),
new Employee("Arun", "VP", null),
new Employee("Arun", "President", "Bangalore"),
new Employee("Rahul", "VP", "Delhi"),
new Employee("Amit", "Manager", null)
);
这里一个(或多个)属性具有 null 值,那么之前起作用的 Java 语句现在给出 NullPointerException。
我的用例是这样的,我希望每个属性中也有空值的频率,所以我不想从列表中过滤掉包含空值的对象。
请为此建议一些优雅的、基于 Java 8 的解决方案。
我将值 null 替换为字符串“null”,以消除 NullPointerException,然后以下似乎工作得很好:
Map<String, Map<String, Long>> attributeFrequencies =
List.stream().flatMap(e -> {
Map<String, String> hm = new HashMap<>();
hm.put(“name”, e.getName());
hm.put(“designation”, e.getDesignation());
hm.put(“address”, e.getAddress());
return hm.entrySet().stream().map(entry -> {
if(entry.getValue() == null) {
entry.setValue(null);
}
return entry;
});
}).collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.groupingBy(
Map.Entry::getValue,
Collectors.counting())));