Java8 List按属性分组成二维数组
在Java开发中,我们经常会遇到需要按照某个属性对列表进行分组的情况。例如,我们有一个学生列表,每个学生有一个学生ID和一个班级ID,我们想要将学生按照班级ID进行分组。
在Java8以前,我们通常使用循环和条件语句来实现这个功能。但是,自从Java8引入了Stream API以及lambda表达式等新特性后,我们可以使用更简洁、高效的方式来实现列表的分组。
让我们来看看如何使用Java8中的Stream API对List按照属性进行分组。
1. 准备数据
我们先创建一个学生类Student
,包含学生ID和班级ID两个属性:
public class Student {
private int studentId;
private int classId;
public Student(int studentId, int classId) {
this.studentId = studentId;
this.classId = classId;
}
public int getStudentId() {
return studentId;
}
public int getClassId() {
return classId;
}
}
然后,我们创建一个学生列表List<Student>
,包含多个学生对象:
List<Student> students = new ArrayList<>();
students.add(new Student(1, 1));
students.add(new Student(2, 1));
students.add(new Student(3, 2));
students.add(new Student(4, 2));
students.add(new Student(5, 3));
students.add(new Student(6, 3));
students.add(new Student(7, 3));
2. 使用Java8的Stream API分组
现在,我们将使用Java8的Stream API来按照班级ID对学生列表进行分组。我们可以使用Collectors.groupingBy
方法来实现分组操作。
Map<Integer, List<Student>> groupedStudents = students.stream()
.collect(Collectors.groupingBy(Student::getClassId));
上述代码使用stream()
方法将学生列表转换为流。然后,我们调用groupingBy
方法,并传入一个函数Student::getClassId
来指定分组的属性。最后,我们将结果存储在一个Map<Integer, List<Student>>
中,其中键是班级ID,值是对应班级的学生列表。
3. 将分组结果转换为二维数组
虽然上述代码已经将学生按照班级ID分组,但是我们可能会需要将分组结果存储在一个二维数组中,以便后续处理。
我们可以使用Java8的Stream API中的map
方法来将分组结果转换为二维数组。
List<List<Student>> groupedStudentsList = new ArrayList<>(groupedStudents.values());
Student[][] groupedStudentsArray = groupedStudentsList.stream()
.map(list -> list.toArray(new Student[0]))
.toArray(Student[][]::new);
上述代码首先使用groupedStudents.values()
获取分组结果的值部分(学生列表),然后使用stream()
方法将其转换为流。接下来,我们调用map
方法,并传入一个lambda表达式,将每个学生列表转换为一个数组。最后,我们使用toArray
方法将流转换为一个二维数组。
4. 完整示例代码
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<Student> students = new ArrayList<>();
students.add(new Student(1, 1));
students.add(new Student(2, 1));
students.add(new Student(3, 2));
students.add(new Student(4, 2));
students.add(new Student(5, 3));
students.add(new Student(6, 3));
students.add(new Student(7, 3));
Map<Integer, List<Student>> groupedStudents = students.stream()
.collect(Collectors.groupingBy(Student::getClassId));
List<List<Student>> groupedStudentsList = new ArrayList<>(groupedStudents.values());
Student[][] groupedStudentsArray = groupedStudentsList.stream()
.map(list -> list.toArray(new Student[0]))
.toArray(Student[][]::new);
System.out.println(Arrays.deepToString(groupedStudentsArray));
}
}
class Student {
private int studentId;
private int classId;
public Student(int studentId, int classId) {
this.studentId = studentId;
this.classId = classId;
}
public int getStudentId() {
return studentId;
}
public int getClassId() {
return classId;