如何用Java Stream计算学生平均分总和并筛选最优学生
修正Java代码实现学生平均分总和计算及最高分学生查找
错误分析
原代码中计算学生平均分总和的逻辑存在两处关键错误:
- 误用
Collectors.groupingBy:该方法用于分组统计,而此处需要将每个学生姓名对应到其平均分总和,应该使用Collectors.toMap - 重复遍历集合:内部嵌套的
averages.entrySet().stream()会遍历整个平均分集合,而非处理当前学生的平均分数据,导致计算结果完全错误
修正后的完整代码
import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; class Student3_1 { private String name; private Map<String, List<Integer>> marks; public Student3_1(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 Function<Map<String, List<Integer>>, Map<String, Double>> averageBySubject = marks -> marks.entrySet().stream().collect(Collectors.toMap( entry -> entry.getKey(), entry -> entry.getValue().stream().mapToDouble(Integer::doubleValue).average().getAsDouble())); public static void main(String[] args) { Map<String, List<Integer>> markAnn = new HashMap<>(); markAnn.put("Physics", List.of(0, 0, 1)); markAnn.put("Mathematics", List.of(0, 0, 0)); markAnn.put("History", List.of(3, 3, 0)); Map<String, List<Integer>> markKate = new HashMap<>(); markKate.put("Physics", List.of(1, 2, 0)); markKate.put("Mathematics", List.of(5, 0, 0)); markKate.put("History", List.of(0, 2, 5)); Map<String, List<Integer>> markBob = new HashMap<>(); markBob.put("Physics", List.of(3, 2, 3)); markBob.put("Mathematics", List.of(2, 2, 3)); markBob.put("History", List.of(4, 4, 3)); Student3_1[] students = {new Student3_1("Ann", markAnn), new Student3_1("Kate", markKate), new Student3_1("Bob", markBob) }; Map<String, Map<String, Double>> averages = Arrays.stream(students) .collect(Collectors.toMap(Student3_1::getName, student -> averageBySubject.apply(student.getMarks()))); System.out.println("各科平均分:" + averages); // 修正:计算每位学生的平均分总和 Map<String, Double> studentSumAverages = averages.entrySet().stream() .collect(Collectors.toMap( Map.Entry::getKey, entry -> entry.getValue().values().stream() .mapToDouble(Double::doubleValue) .sum() )); System.out.println("平均分总和:" + studentSumAverages); // 找出平均分总和最高的学生 Map.Entry<String, Double> topStudent = studentSumAverages.entrySet().stream() .max(Map.Entry.comparingByValue()) .orElse(null); if (topStudent != null) { System.out.println("最聪明的学生:" + topStudent.getKey() + ",总分:" + topStudent.getValue()); } } }
关键修正说明
- 计算平均分总和:使用
Collectors.toMap将每个学生姓名映射到其各科平均分的总和,通过entry.getValue().values().stream().mapToDouble(Double::doubleValue).sum()直接计算当前学生的平均分总和 - 查找最高分学生:通过
stream().max(Map.Entry.comparingByValue())找出总和最大的学生条目,处理空值情况避免异常
内容的提问来源于stack exchange,提问作者Kto Tam
相关产品推荐
相关产品推荐

