Java 8 中的集合按多个属性分组

在 Java 8 中,Stream API 的引入为集合处理提供了强大的功能,特别是在数据分组和统计方面。通过使用 Collectors.groupingBy() 方法,我们可以根据某些属性对集合中的元素进行分组。本文将向您展示如何根据多个属性进行分组,并提供相关的代码示例和 UML 状态图与类图。

代码示例

假设我们有一个 Student 类,表示学生的基本信息,包括姓名、成绩和年级。我们希望根据 gradescore 属性对学生进行分组。

import java.util.*;
import java.util.stream.Collectors;

class Student {
    private String name;
    private int score;
    private String grade;

    public Student(String name, int score, String grade) {
        this.name = name;
        this.score = score;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public int getScore() {
        return score;
    }

    public String getGrade() {
        return grade;
    }

    @Override
    public String toString() {
        return String.format("%s (Grade: %s, Score: %d)", name, grade, score);
    }
}

public class GroupByMultipleAttributes {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student("Alice", 90, "A"),
                new Student("Bob", 80, "A"),
                new Student("Cathy", 85, "B"),
                new Student("David", 70, "B"),
                new Student("Eva", 95, "A")
        );

        Map<String, Map<Integer, List<Student>>> grouped = students.stream()
                .collect(Collectors.groupingBy(Student::getGrade,
                        Collectors.groupingBy(Student::getScore)));

        System.out.println(grouped);
    }
}

在上面的例子中,我们创建了一个 Student 类,并在 main 方法中初始化了一个学生列表。通过 stream() 方法,我们对学生列表进行了流处理,并通过 Collectors.groupingBy() 方法按 gradescore 属性进行了分组。最终,我们得到了一个嵌套的 Map,其中外层的键是年级,内层的键是分数,值是属于该分组的学生列表。

状态图

以下是表示整个分组过程的状态图,其中展示了输入数据的流转状态:

stateDiagram
    [*] --> InputData
    InputData --> StreamCreation
    StreamCreation --> GroupingByGrade
    GroupingByGrade --> GroupingByScore
    GroupingByScore --> Result

类图

接下来是显示 Student 类的类图,解释其属性和方法:

classDiagram
    class Student {
        +String name
        +int score
        +String grade
        +String getName()
        +int getScore()
        +String getGrade()
        +String toString()
    }

总结

Java 8 的 Stream API 给我们提供了灵活而强大的处理集合的手段,特别是在需要按多个属性进行数据分组的场景中。通过本示例,我们展示了如何使用 Collectors.groupingBy() 方法根据多个属性进行分组,并通过 UML 图形展示了分组过程的状态和类结构。

这种方法不仅可以简化代码,提高可读性,而且还可以使我们更快地处理复杂的数据集合操作。希望您能在实际开发中应用这些技术,优化您的数据处理流程。