数值计算应全程使用原始类型避免装箱拆箱,如用int[]替代list、long代替long作累加器、intstream替代stream,并警惕null和缓存范围外的==比较。

在数值计算中频繁触发自动装箱和拆箱,会显著拖慢执行速度、增加内存分配压力,并加重垃圾回收负担。关键不是写法看起来简洁,而是字节码层面是否引入了 valueOf()、xxxValue()、new 或 checkcast 这类指令。优化核心是让计算路径全程走原始类型,把包装类操作隔离到边界。
用原始类型数组替代包装类集合
集合如 List<integer></integer> 每次 get() 都要拆箱,每次 add() 都要装箱;而 int[] 直接读写栈上值,无对象开销。
- 将
List<integer> list = new ArrayList();</integer>改为int[] data = new int[n]; - 避免
Arrays.asList(intArray)—— 它返回的是List<integer></integer>,底层全装箱 - 批量处理时,先用
stream().mapToInt(Integer::intValue).toArray()一次性转成原始数组,再进循环
循环变量和累加器保持基本类型
像 Long sum = 0L; for (int i = 0; i 看似简单,实际每次迭代都发生一次拆箱(<code>sum.longValue())加一次装箱(Long.valueOf(...))。
- 把累加器声明为
long sum = 0L;,而非Long sum = 0L; - 循环变量也用
int i或long i,不写Integer i - 若需流式处理,优先选
IntStream.range(0, n),它内部运算全程使用int,不生成包装对象
警惕缓存范围外的 == 比较与 null 场景
装箱复用缓存仅限 -128 ~ 127(Integer),超出范围的对象比较用 == 会误判;而拆箱遇到 null 直接抛 NullPointerException。
- 数值比较统一用
.equals()或先转基本类型再比,例如Objects.equals(a, b) - 从集合取值后,先判空再拆箱:
if (obj != null) result += obj.intValue(); - 避免在可能为
null的包装类上调用算术运算,如someInteger + 1
必要时选用原始类型集合库
标准集合无法绕过泛型擦除导致的装箱,但第三方库如 Eclipse Collections 的 IntList 或 Trove 的 TIntArrayList 在字节码中全程使用 iload/istore 和 iadd,无任何引用操作。
- 适合高频数值运算、大数据量统计、矩阵运算等性能敏感场景
- 初始化成本略高,但运行期零装箱/拆箱,长期看收益明显
- 注意 API 风格差异,需适配现有逻辑结构
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











