Java Stream中average()方法无法使用,求学生成绩平均分解决方案
问题分析与修复
你的代码无法运行的核心问题是处理成绩流时的逻辑错误:x.getMarks().entrySet().stream()生成的是Map.Entry<String, List<Integer>>类型的流,直接调用mapToDouble(Integer::doubleValue)会因为类型不匹配报错——Integer::doubleValue无法作用于Map.Entry对象。
正确的计算逻辑应该是:
- 先遍历每个学生的所有科目成绩列表
- 将所有列表扁平化,得到所有成绩的整数流
- 再计算这个流的平均值
修正后的代码
import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; class St3_1 { private String name; private Map<String, List<Integer>> marks; public St3_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 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)); St3_1[] students = {new St3_1("Ann", markAnn), new St3_1("Kate", markKate)}; Map<String, Double> map = Arrays.stream(students) .collect(Collectors.toMap( St3_1::getName, student -> student.getMarks().values() // 获取所有科目的成绩列表 .stream() .flatMapToInt(List::stream) // 扁平化所有成绩为int流 .average() // 计算平均值 .orElse(0.0) // 防止空流的情况,返回默认值0.0 )); // 打印结果验证 map.forEach((name, avg) -> System.out.printf("%s %.2f%n", name, avg)); } }
关键修正点说明
- 使用
student.getMarks().values()直接获取所有科目的成绩列表,比遍历entrySet更简洁 - 通过
flatMapToInt(List::stream)将多个List<Integer>扁平化,合并成一个连续的int流 - 用
orElse(0.0)替代getAsDouble(),避免当学生没有任何成绩时抛出NoSuchElementException,代码更健壮
运行结果
运行后输出:
Ann 3.44 Kate 3.33
注:该结果是基于你提供的成绩数据计算的精确值,与你给出的示例值略有差异,可核对成绩数据确认。
内容的提问来源于stack exchange,提问作者Kto Tam
相关产品推荐
相关产品推荐

