如何使用Stream API计算全体学生指定学科的平均成绩?
用Stream API计算全体学生指定学科的平均成绩
两种数据格式的处理方案
一、处理给定的Student类数组数据
针对你提供的Student类结构(每个学生用Map<String, List<Integer>>存储学科多次成绩),可以通过Stream API快速计算指定学科的全体平均分,直接在Student类的main方法中添加计算逻辑即可:
import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; class Student { private String name; private Map<String, List<Integer>> marks; public Student(String name, Map<String, List<Integer>> marks) { this.name = name; this.marks = marks; } public String getName() { return name; } public Map<String, List<Integer>> getMarks() { return marks; } public static void main(String[] args) { // 初始化学生成绩 Map<String, List<Integer>> markAnn = new HashMap<>(); markAnn.put("Physics", List.of(4, 4, 5)); markAnn.put("Mathematics", List.of(2, 3, 4)); markAnn.put("History", List.of(3, 3, 3)); Map<String, List<Integer>> markKate = new HashMap<>(); markKate.put("Physics", List.of(1, 2, 3)); markKate.put("Mathematics", List.of(5, 5, 3)); markKate.put("History", List.of(4, 2, 5)); Student[] students = {new Student("Ann", markAnn), new Student("Kate", markKate)}; // 指定要计算的学科 String targetSubject = "Physics"; // Stream API计算平均分 double average = Arrays.stream(students) // 提取目标学科成绩,无则返回空列表避免空指针 .map(student -> student.getMarks().getOrDefault(targetSubject, Collections.emptyList())) // 把多个成绩列表合并成单个成绩流 .flatMap(List::stream) // 转为double类型计算 .mapToDouble(Integer::doubleValue) // 计算平均,无有效成绩时返回0.0 .average() .orElse(0.0); System.out.printf("全体学生%s的平均成绩为:%.2f%n", targetSubject, average); } }
核心逻辑说明:
getOrDefault处理学生无目标学科成绩的场景,避免空指针异常flatMap将分散的成绩列表扁平化,转化为连续的成绩流average()返回OptionalDouble,用orElse(0.0)兜底无有效成绩的情况
二、处理HashMap<String, String>格式数据
对于键为学生姓名、值为"学科1 成绩1 学科2 成绩2..."格式的HashMap,需要先解析字符串提取目标学科成绩,再计算平均,示例代码:
import java.util.HashMap; import java.util.Objects; public class ScoreCalculator { public static void main(String[] args) { // 初始化HashMap格式的学生成绩 HashMap<String, String> studentScores = new HashMap<>(); studentScores.put("Ann", "Physics 3.5 Math 4.0 History 2.5"); studentScores.put("Kate", "Physics 2.0 Math 4.5 History 3.0"); studentScores.put("Bob", "Math 3.0 History 2.8"); // Bob无Physics成绩 String targetSubject = "Physics"; double average = studentScores.entrySet().stream() .map(entry -> { String[] parts = entry.getValue().split(" "); // 按「学科-成绩」的成对格式遍历匹配 for (int i = 0; i < parts.length; i += 2) { if (parts[i].equals(targetSubject)) { return Double.parseDouble(parts[i+1]); } } return null; // 无目标学科成绩则返回null }) .filter(Objects::nonNull) // 过滤掉无目标学科成绩的学生 .mapToDouble(Double::doubleValue) .average() .orElse(0.0); System.out.printf("全体学生%s的平均成绩为:%.2f%n", targetSubject, average); } }
核心逻辑说明:
- 按空格拆分成绩字符串,步长为2遍历匹配目标学科,提取对应成绩
filter(Objects::nonNull)排除无有效成绩的条目- 同样用
orElse(0.0)处理无数据的边界场景
内容的提问来源于stack exchange,提问作者Joe Black
相关产品推荐
相关产品推荐

