java数组求平均值需注意int除法截断和空数组异常:应将sum转double再除,且stream计算前须判空;for循环性能优于stream;bigdecimal仅适用于金融等需精确小数的场景。

Java数组求平均值时int除法自动截断怎么办
直接用 int 数组求和再除以长度,结果一定是整数——哪怕你声明了 double 接收变量。因为 sum / length 这一步在运算时还是两个 int,JVM 先做整除,再转 double,精度早就丢了。
- 错误写法:
double avg = sum / arr.length;(sum和arr.length都是int) - 正确做法:至少让其中一个操作数变成
double,比如sum * 1.0 / arr.length或(double) sum / arr.length - 更安全的写法是先转
double再除,避免大整数溢出(如int求和可能溢出,但转long再转double更稳)
用Stream计算double数组平均值遇到Optional.empty异常
Arrays.stream(arr).average() 对空数组返回 OptionalDouble.empty(),不判空就调 getAsDouble() 会抛 NoSuchElementException。这不是“没结果”,是设计上强制你处理边界情况。
- 必须检查:用
orElse(0.0)或orElseThrow(() -> new IllegalArgumentException("empty array")) -
int数组不能直接用IntStream.average()得到double?错,它返回的就是OptionalDouble,和DoubleStream一致 - 注意:
IntStream.average()内部已自动把int转double算,不用手动强转,但空数组逻辑不变
大数据量下用for循环比Stream.average()快多少
纯数值遍历场景下,传统 for 循环通常快 2–5 倍,尤其当数组长度超 10 万。Stream 的装箱、管道开销、额外对象分配(如 OptionalDouble)在简单聚合里全是冗余成本。
- 能用
for就别为“函数式”硬套 Stream,除非你要链式组合过滤/映射 - 如果坚持用 Stream,确保数组非空且类型匹配:用
IntStream.of(arr)而不是Arrays.stream(arr)(后者对int[]会变成Stream<int></int>,编译都过不去) - 性能差异在 Android 或嵌入式环境会更明显,JIT 优化对简单循环更友好
BigDecimal算平均值适合哪些场景
只有当你需要精确小数位控制(比如金融计算要求保留两位小数、四舍五入规则严格),才值得上 BigDecimal。日常统计、科学计算、日志指标这类场景,double 完全够用,还更快更省内存。
立即学习“Java免费学习笔记(深入)”;
- 别一上来就用
BigDecimal.valueOf(arr[i])循环加——double到BigDecimal的构造本身就有精度陷阱(如0.1存不精确) - 如果原始数据是字符串或整数分母(如“123元/4人”),优先用
BigDecimal(String)构造,避免double中间态 - 除法必须指定
scale和RoundingMode,否则抛ArithmeticException(无限小数)
整除截断和空数组异常是最常踩的两个坑,前者改一个类型转换就能修,后者漏一次判空就崩。别被“平均值很简单”带偏——Java 的类型推导和 Optional 设计,都在逼你显式面对这些细节。










