Java8 处理一对多集合

在软件开发中,我们经常遇到需要处理一对多的数据集合的情况。例如,我们可能需要根据学校查询所有学生的信息,或者根据用户查询其所有订单的信息。在Java8中,引入了一些便捷的方式来处理这种一对多的关系,使得代码编写更加简洁和易读。

1. 使用Map和Collectors.groupingBy方法

Map是一种键值对的数据结构,在Java中,我们可以使用Map来存储一对多的关系。Java8提供了Collectors.groupingBy方法,可以方便地将一个集合按照指定的条件分组。下面是一个示例代码:

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class GroupingExample {
    public static void main(String[] args) {
        // 创建一个学生列表
        List<Student> students = List.of(
                new Student(1, "Tom", 18),
                new Student(2, "Jerry", 19),
                new Student(3, "Alice", 20),
                new Student(4, "Bob", 20),
                new Student(5, "John", 19)
        );

        // 将学生按照年龄分组
        Map<Integer, List<Student>> studentByAge = students.stream()
                .collect(Collectors.groupingBy(Student::getAge));

        // 输出结果
        studentByAge.forEach((age, studentList) -> {
            System.out.println("Age: " + age);
            studentList.forEach(student -> System.out.println("  " + student.getName()));
        });
    }
}

class Student {
    private int id;
    private String name;
    private int age;

    // 省略构造方法和getter/setter方法

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

在上面的代码中,我们首先创建了一个学生列表,然后使用Collectors.groupingBy方法将学生按照年龄分组,得到一个Map<Integer, List<Student>>类型的结果。最后,我们遍历这个结果并输出每个年龄对应的学生列表。

2. 使用flatMap方法和Stream流

在Java8中,引入了flatMap方法,可以将一个多维的数据结构转换成一个一维的数据结构。结合Stream流的操作,我们可以很方便地处理一对多的集合。下面是一个示例代码:

import java.util.List;

public class FlatMapExample {
    public static void main(String[] args) {
        // 创建一个学生列表
        List<Student> students = List.of(
                new Student(1, "Tom", 18),
                new Student(2, "Jerry", 19),
                new Student(3, "Alice", 20),
                new Student(4, "Bob", 20),
                new Student(5, "John", 19)
        );

        // 使用flatMap将多个学生的课程列表合并成一个列表
        List<String> courseList = students.stream()
                .flatMap(student -> student.getCourses().stream())
                .distinct()
                .collect(Collectors.toList());

        // 输出结果
        courseList.forEach(System.out::println);
    }
}

class Student {
    private int id;
    private String name;
    private int age;
    private List<String> courses;

    // 省略构造方法和getter/setter方法

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", courses=" + courses +
                '}';
    }
}

在上面的代码中,我们首先创建了一个学生列表,每个学生有一个课程列表。我们使用flatMap方法将多个学生的课程列表合并成一个列表,并去重最后输出。

3. 使用join方法和Collectors.joining方法

在Java8中,String类新增了一个join方法,可以将一个集合的元素以指定的分隔符连接起来。结合Collectors.joining方法,我们可以很方便地处理一对多的集合。下面是一个示例代码:

import java.util.List;
import java.util.stream.Collectors;

public class JoinExample {
    public static void main(String[] args) {
        // 创建一个学生列表
        List<Student> students = List.of(
                new Student(1, "Tom", 18),
                new Student(2, "Jerry", 19