Java8中List按多个字段分组和映射
在Java编程中,我们经常需要对列表进行分组和映射操作。而在Java 8中,引入了lambda表达式和Stream API,使得这些操作更加简洁和高效。本文将介绍如何使用Java 8对List按多个字段进行分组和映射的方法,并提供相应的代码示例。
为什么需要按多个字段分组和映射
在数据处理中,有时候我们需要根据多个字段来对数据进行分类和聚合,这样可以更精准地对数据进行分析和处理。比如,我们有一个包含员工信息的列表,我们希望按照部门和性别对员工进行分组,并统计每个部门每种性别的人数。这时候就需要按照多个字段进行分组和映射操作。
使用Java 8对List进行多字段分组
在Java 8中,我们可以使用Stream API中的Collectors.groupingBy
方法来对List进行分组操作。对于多字段分组,我们可以使用Collectors.groupingBy
方法的重载版本,传入多个分类器即可实现按多个字段分组的功能。
下面是一个示例代码,演示了如何对员工列表按照部门和性别进行分组:
import java.util.*;
import java.util.stream.Collectors;
class Employee {
private String department;
private String gender;
public Employee(String department, String gender) {
this.department = department;
this.gender = gender;
}
public String getDepartment() {
return department;
}
public String getGender() {
return gender;
}
}
public class GroupingByMultipleFields {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("HR", "Male"),
new Employee("HR", "Female"),
new Employee("IT", "Male"),
new Employee("IT", "Female")
);
Map<String, Map<String, List<Employee>>> groupedByDepartmentAndGender = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.groupingBy(Employee::getGender)));
groupedByDepartmentAndGender.forEach((department, genderMap) -> {
System.out.println(department + ": ");
genderMap.forEach((gender, employeeList) -> {
System.out.println(" " + gender + ": " + employeeList.size());
});
});
}
}
在上面的代码中,我们首先创建了一个Employee类来表示员工信息,包含部门和性别两个字段。然后创建了一个包含员工信息的列表,并使用Collectors.groupingBy
方法按照部门和性别进行分组,最后输出每个部门每种性别的员工人数。
使用Java 8对List进行多字段映射
除了分组操作,有时候我们还需要对分组后的数据进行映射处理,比如统计每个部门每种性别的平均工资。在Java 8中,我们可以使用Collectors.collectingAndThen
方法来对分组后的数据进行进一步处理。
下面是一个示例代码,演示了如何对员工列表按照部门和性别进行分组,并计算每个部门每种性别的平均工资:
import java.util.*;
import java.util.stream.Collectors;
class Employee {
private String department;
private String gender;
private double salary;
public Employee(String department, String gender, double salary) {
this.department = department;
this.gender = gender;
this.salary = salary;
}
public String getDepartment() {
return department;
}
public String getGender() {
return gender;
}
public double getSalary() {
return salary;
}
}
public class MappingByMultipleFields {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("HR", "Male", 5000),
new Employee("HR", "Female", 6000),
new Employee("IT", "Male", 7000),
new Employee("IT", "Female", 8000)
);
Map<String, Map<String, Double>> averageSalaryByDepartmentAndGender = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment,
Collectors.groupingBy(Employee::getGender,
Collectors.collectingAndThen(
Collectors.averagingDouble(Employee::getSalary),
avg -> Math.round(avg * 100.0) / 100.0))));
averageSalaryByDepartmentAndGender.forEach((department, gender