一、背景介绍
在Java中,List是最常用的集合类型之一,它可以存储任何类型的对象,但在实际开发中,我们有时需要按照某种属性或者字段对List中的元素进行分组,这可以通过Java8中新增的Stream API来实现。
二、具体实现步骤
1.创建一个包含多个元素的List集合,例如:
List<Student> students = new ArrayList<>();
students.add(new Student("Tom", "math", 85));
students.add(new Student("Tom", "english", 90));
students.add(new Student("Mary", "math", 92));
students.add(new Student("Mary", "english", 87));
2.使用Stream API对List进行分组,例如按照学生姓名进行分组
Map<String, List<Student>> groupByName = students.stream().collect(Collectors.groupingBy(Student::getName));
这里使用了Stream中的groupingBy()方法来对List进行分组,需要提供一个按照哪个属性分组的条件,该方法会返回一个Map对象,其中键为分组条件,值为List集合,即按照该条件分组后的结果。
3.使用Stream API进一步处理分组结果,例如计算每个分组的平均分
Map<String, Double> avgScoreByName = groupByName.entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, v -> {
List<Student> list = v.getValue();
double sumScore = list.stream().mapToInt(Student::getScore).sum();
return sumScore / list.size();
}));
这里使用了Stream中的toMap()方法将分组结果转换成键值对形式,并对每个分组求出平均分。其中,我们使用了EntrySet()方法获取Map中的键值对,并展开进行处理。
三、示例说明
示例一:按照性别对员工进行分组
假设我们有一个Employee类,其中包含了员工的姓名、性别和工资三个属性,现在我们需要按照性别对所有员工进行分组,并统计每个分组的平均工资。
public class Employee {
private String name;
private String sex;
private double salary;
public Employee(String name, String sex, double salary) {
this.name = name;
this.sex = sex;
this.salary = salary;
}
//getter、setter方法
}
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("Tom", "Male", 5000));
employees.add(new Employee("Jane", "Female", 6000));
employees.add(new Employee("John", "Male", 4000));
employees.add(new Employee("Lucy", "Female", 7000));
Map<String, Double> groupBySex = employees.stream().collect(Collectors.groupingBy(Employee::getSex, Collectors.averagingDouble(Employee::getSalary)));
这里我们使用了两级分组,首先按照性别进行分组,然后对每个分组进行平均工资的计算,最终输出结果为:
{Female=6500.0, Male=4500.0}
示例二:按照省份进行多级分组
假设我们有一个Person类,其中包含了人员的姓名、年龄和省份三个属性,现在我们需要按照省份对所有人进行分组,并统计每个省份中不同年龄段的人员数量。
public class Person {
private String name;
private int age;
private String province;
public Person(String name, int age, String province) {
this.name = name;
this.age = age;
this.province = province;
}
//getter、setter方法
}
List<Person> persons = new ArrayList<>();
persons.add(new Person("Tom", 20, "Guangdong"));
persons.add(new Person("Jane", 25, "Guangdong"));
persons.add(new Person("John", 30, "Guangdong"));
persons.add(new Person("Lucy", 35, "Guangxi"));
persons.add(new Person("Steven", 40, "Guangxi"));
persons.add(new Person("Bob", 45, "Guangxi"));
Map<String, Map<Integer, Long>> groupByProvinceAndAge = persons.stream()
.collect(Collectors.groupingBy(Person::getProvince, Collectors.groupingBy(p -> p.getAge() / 10, Collectors.counting())));
这里我们也使用了两级分组,其中第一级按照省份进行分组,第二级按照年龄段进行分组,并计算每个分组中的人员数量。最终输出结果为:
{
Guangdong={
2=1,
3=1,
4=1
},
Guangxi={
3=1,
4=2
}
}
其中,Guangdong省中有2个20~30岁的人员、1个30~40岁的人员和1个40~50岁的人员;Guangxi省中有1个30~40岁的人员和2个40~50岁的人员。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:List集合按某个属性或者字段进行分组的操作 - Python技术站