Java 8下统计含Null值POJO属性值频率的优雅方案
统计Employee属性值(含Null)的出现频率
问题背景
现有如下Employee类:
class Employee { String name; String designation; String address; // Getters and setters // All args constructor }
需要统计该类对象列表中每个属性的所有值(包括Null值)的出现频率。例如给定列表:
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} }
原代码在无Null值时可正常运行,但当属性值为Null时会抛出NullPointerException:
// 原代码(Java 9+,存在Null值时抛NPE) 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())));
问题原因
- 原代码使用的
Map.of()是Java 9引入的方法,该方法不允许值为Null,当属性值为Null时,创建Map的环节直接抛出NPE。 - Java 8本身没有
Map.of()方法,原代码在Java 8环境下无法编译。
Java 8解决方案
替换Map.of()为支持Null值的HashMap构建属性映射,其余逻辑保持不变:
Map<String, Map<String, Long>> attributeFrequencies = list.stream() .flatMap(e -> { // 用HashMap存储属性键值对,支持Null值 Map<String, String> attributes = new HashMap<>(); attributes.put("name", e.getName()); attributes.put("designation", e.getDesignation()); attributes.put("address", e.getAddress()); return attributes.entrySet().stream(); }) .collect(Collectors.groupingBy( Map.Entry::getKey, // 按属性名分组 Collectors.groupingBy( Map.Entry::getValue, // 按属性值分组(支持Null作为key) Collectors.counting() // 统计次数 ) ));
效果验证
对于包含Null值的列表:
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值的统计:
{ name = {Rahul=1, Arun=2, Amit=2}, designation = {President=1, VP=2, Manager=2}, address = {Delhi=2, Bangalore=1, null=2} }
内容的提问来源于stack exchange,提问作者Mayank
相关产品推荐
相关产品推荐

