在Java8中,可以使用Collectors.groupingBy
方法对List集合根据属性进行分组。以下是一个完整的示例,展示如何根据对象的不同属性分组。
根据对象属性分组
假设有一个Student
类,包含name
、age
和grade
属性:
public class Student {private String name;private int age;private String grade;// 构造方法、Getter和Setter省略
}
按单一属性分组(如grade)
List<Student> students = Arrays.asList(new Student("Alice", 20, "A"),new Student("Bob", 21, "B"),new Student("Charlie", 20, "A")
);Map<String, List<Student>> groupedByGrade = students.stream().collect(Collectors.groupingBy(Student::getGrade));System.out.println(groupedByGrade);
输出结果:
{A=[Student{name='Alice', age=20, grade='A'}, Student{name='Charlie', age=20, grade='A'}],B=[Student{name='Bob', age=21, grade='B'}]
}
按多个属性分组(复合键)
如果需要根据多个属性分组(如age
和grade
),可以使用Collectors.groupingBy
结合复合键:
Map<List<Object>, List<Student>> groupedByAgeAndGrade = students.stream().collect(Collectors.groupingBy(student -> Arrays.asList(student.getAge(), student.getGrade())));System.out.println(groupedByAgeAndGrade);
输出结果:
{[20, A]=[Student{name='Alice', age=20, grade='A'}, Student{name='Charlie', age=20, grade='A'}],[21, B]=[Student{name='Bob', age=21, grade='B'}]
}
分组后计算(如计数、求和)
可以使用Collectors.groupingBy
结合其他收集器进行聚合操作:
// 按grade分组并计算每组的数量
Map<String, Long> countByGrade = students.stream().collect(Collectors.groupingBy(Student::getGrade,Collectors.counting()));System.out.println(countByGrade); // 输出:{A=2, B=1}
分组后映射(提取特定属性)
// 按grade分组并提取name列表
Map<String, List<String>> namesByGrade = students.stream().collect(Collectors.groupingBy(Student::getGrade,Collectors.mapping(Student::getName, Collectors.toList())));System.out.println(namesByGrade); // 输出:{A=[Alice, Charlie], B=[Bob]}
并行流分组
对于大数据集,可以使用并行流提高性能:
Map<String, List<Student>> parallelGrouped = students.parallelStream().collect(Collectors.groupingBy(Student::getGrade));
以上方法涵盖了Java8中对List集合按属性分组的常见场景,包括单一属性、复合键分组以及分组后的聚合操作。