必须先mapToInt,因为Stream<Integer>无average()方法,只有IntStream等原始类型流支持数值聚合;mapToInt将对象流转为int流后才能调用average()得到OptionalDouble,需用orElse等安全解包。

直接用 mapToInt 转成 IntStream,再调用 average() 就能一行算出平均分,结果是 OptionalDouble,记得安全解包。
为什么必须先 mapToInt?
Stream<Integer> 本身没有 average() 方法,只有原始类型流(如 IntStream、DoubleStream)才支持数值聚合。而 mapToInt 的作用就是把对象流里的每个元素转成 int,生成可计算的 IntStream。
常见错误写法:students.stream().map(s -> s.getScore()).average() —— 编译不通过。
基本用法:一行搞定平均分
假设成绩存在 List<Integer> 或对象列表中:
- 从
List<Integer>计算:
double avg = scores.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0.0); // 空列表时返回 0.0
- 从学生对象列表提取成绩:
double avg = students.stream()
.mapToInt(Student::getScore)
.average()
.orElse(0.0);
注意空集合和 OptionalDouble 的处理
average() 永远返回 OptionalDouble,因为流可能为空——这时调用 getAsDouble() 会抛 NoSuchElementException。
立即学习“Java免费学习笔记(深入)”;
推荐做法:
- 用
orElse(double)提供默认值(如 0.0 或 -1) - 用
orElseThrow(() -> new RuntimeException("无成绩数据"))显式报错 - 用
ifPresent(System.out::println)仅在有值时消费
进阶:过滤无效成绩后再算平均
实际场景中可能需要排除缺考(如成绩为 -1)或异常值:
double avg = students.stream().filter(s -> s.getScore() >= 0 && s.getScore() .mapToInt(Student::getScore)
.average()
.orElse(0.0);
过滤和映射顺序不重要,但建议先 filter 再 mapToInt,避免对无效数据做多余转换。


















