在 Java 中,int[](基本类型数组)和 ArrayList<Integer>(集合类)最本质的区别在于:一个是“原生的物理内存块”,一个是“封装好的逻辑容器”。
简单来说,int[] 是为了极致性能而生的,而 ArrayList 是为了开发效率而生的。
1. 核心差异对比表
| 特性 | int[] (原生数组) | ArrayList<Integer> (集合) |
| 长度 | 固定。一旦创建,无法改变大小。 | 动态。会自动扩容(通常是 1.5 倍)。 |
| 存储类型 | 只能存 基本类型 (int)。 |
只能存 引用类型 (Integer)。 |
| 性能 | 极高。直接操作内存,无额外开销。 | 较低。涉及装箱/拆箱以及对象头开销。 |
| 功能/方法 | 极少。只有 .length 属性。 |
丰富。有 .add(), .remove(), .sort() 等。 |
| 内存连续性 | 绝对连续,对 CPU 缓存友好。 | 逻辑连续。数组里存的是对象的引用地址。 |
2. 深度拆解:为什么 ArrayList 慢一点?
① 自动装箱(Autoboxing)
ArrayList 不能直接存 int,它存的是 Integer 对象。
当你执行 list.add(10) 时,Java 实际上偷偷做了这件事:list.add(Integer.valueOf(10))。
-
后果:这产生了一个对象。如果你有 100 万个数字,
int[]只占用约 4MB 内存,而ArrayList<Integer>加上对象头和引用,可能占用 16MB-20MB。
② 扩容成本
-
int[]:如果你发现数组满了,你必须手动new一个更大的数组,然后用System.arraycopy把数据拷过去。 -
ArrayList:它帮你做好了这一切。但“扩容”是一个 $O(n)$ 的操作,如果频繁触发,会造成瞬间的性能抖动。
3. 什么时候用哪个?
选 int[] 的场景:
-
性能敏感型算法:比如你要写一个处理千万级数据的 RSA 签名脚本 或者 比特币私钥生成工具。
-
内存极其受限:比如在 Android 底层开发或者嵌入式环境中。
-
多维矩阵运算:比如
int[][]。
选 ArrayList 的场景:
-
绝大多数业务开发:比如你从数据库查出一批用户 ID,你不知道会有多少个。
-
需要频繁增删:利用
ArrayList丰富的 API。 -
与泛型配合:如果你需要把数据传递给其他使用
List<T>的接口。
4. 你的业务场景(比特币私钥生成)
在你之前的代码中,如果你要生成 32 字节的私钥:
// 推荐用这个,因为私钥长度固定为 32,int[](或 byte[])性能最强且逻辑清晰
byte[] privateKey = new byte[32];
// 不推荐用这个,因为没必要为了固定长度的 32 个数去承担 Integer 对象的开销
List<Integer> list = new ArrayList<>();
总结
-
int[]是快而稳的货车,载货量固定,拉重活首选。 -
ArrayList是智能的私家车,座位不够能自动变长,操作丝滑。
既然聊到了性能,你想了解一下 Java 8 之后为了兼顾“集合的方便”和“数组的性能”而推出的 IntStream 吗?它可以让你像操作 List 一样操作原生的 int 数组。