MST

星途 面试题库

面试题:Java Stream API与Lambda表达式的复杂数据处理

假设有一个包含学生对象的List,每个学生对象有姓名、年龄、成绩等属性。请使用Stream API和Lambda表达式,按照年龄对学生进行分组,然后在每个年龄组内,找出成绩最高的学生,并将结果以Map< Integer, Student>的形式返回。说明在处理过程中如何处理可能出现的空指针等异常情况。
45.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

以下是使用Java 8的Stream API和Lambda表达式实现该功能的代码:

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

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public int getScore() {
        return score;
    }

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

public class Main {
    public static Map<Integer, Student> findHighestScoringStudentByAge(List<Student> students) {
        if (students == null) {
            throw new IllegalArgumentException("学生列表不能为null");
        }

        return students.stream()
               .filter(Objects::nonNull)
               .collect(Collectors.groupingBy(
                        Student::getAge,
                        Collectors.collectingAndThen(
                                Collectors.maxBy(Comparator.comparingInt(Student::getScore)),
                                Optional::orElse(null)
                        )
                ));
    }

    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student("Alice", 20, 85),
                new Student("Bob", 21, 90),
                new Student("Charlie", 20, 92),
                new Student("David", 22, 88),
                null
        );

        Map<Integer, Student> result = findHighestScoringStudentByAge(students);
        result.forEach((age, student) -> System.out.println("年龄 " + age + ": " + student));
    }
}

代码说明

  1. 空指针处理

    • findHighestScoringStudentByAge方法中,首先对传入的students列表进行非空检查,如果为null,则抛出IllegalArgumentException
    • 使用stream().filter(Objects::nonNull)对列表中的学生对象进行过滤,确保在后续操作中不会出现空指针异常。
  2. 按年龄分组并找出最高分学生

    • 使用Collectors.groupingBy方法按年龄对学生进行分组。
    • 在分组的下游收集器中,使用Collectors.collectingAndThenCollectors.maxBy找出每个年龄组中成绩最高的学生。
    • Collectors.maxBy返回一个Optional对象,使用Optional::orElse(null)处理可能为空的情况,即某个年龄组没有学生(这种情况在实际中比较少见,但代码处理了这种边界情况)。
  3. 测试

    • main方法中创建了一个包含学生对象的列表,其中包含一个null元素,用于测试空指针处理。
    • 调用findHighestScoringStudentByAge方法并打印结果。