Java中数组长度固定且支持基本类型、随机访问快但无内置方法;集合可自动扩容、提供丰富API但需包装类、性能和行为依实现类而异,选型应基于具体操作需求。

数组长度固定,集合能自动扩容
Java里一旦写 new String[5],这个数组就锁死5个位置,想加第6个元素?不行——不是报错就是得手动创建新数组、复制旧数据、再赋值。而 ArrayList 调用 add() 时,底层会检测容量,自动扩容(通常是1.5倍),你完全不用管它怎么搬数据。
- 常见错误:用数组存日志记录,但日志条数不可预估,结果某天突然
ArrayIndexOutOfBoundsException - 真实场景:读取CSV文件行数未知 → 用
ArrayList;配置项明确只有4个开关 → 用boolean[4]更轻量 - 注意:
ArrayList扩容有复制开销,高频增删建议用LinkedList或预设初始容量,如new ArrayList(1024)
数组支持基本类型,集合必须用包装类
你可以直接声明 int[]、double[],内存里存的就是原始数值;但所有集合(ArrayList、HashSet 等)只能放引用类型,所以存整数得写 ArrayList,背后是自动装箱/拆箱。
- 性能影响:高频循环中对
Integer做算术运算(比如sum += list.get(i)),可能触发大量临时对象创建和GC - 坑点:
Integer a = 127; Integer b = 127; System.out.println(a == b); // true,但a = 128; b = 128;就是false—— 这是缓存机制,跟数组的==比较行为完全不同 - 替代方案:如果纯数值计算密集,且数量大,优先考虑
int[]+ 手动逻辑,或使用IntStream配合原始类型操作
数组靠索引随机访问快,集合依赖实现类
arr[3] 是真正的 O(1):地址 = 起始地址 + 3 × 单元素字节长;而 list.get(3) 是否快,取决于 list 是什么——ArrayList 是 O(1),LinkedList 是 O(n),因为要从头遍历3次指针。
- 误用典型:把
LinkedList当成“更快的 ArrayList”用,频繁调get(i),性能暴跌 - 查元素存在性:
array没内置方法,得自己写循环或用Arrays.asList(arr).contains(x)(注意这会把基本类型数组转成含单个元素的列表!);HashSet的contains()才是真 O(1) - 记住口诀:要按位置反复读 → 选
ArrayList;要频繁在头部/中间插入删除 → 选LinkedList;要快速去重查重 → 选HashSet
数组没有方法,集合自带全套API
数组连个 sort() 都没有,排序得调 Arrays.sort(arr);而 list.sort(Comparator.naturalOrder())、list.removeIf(x -> x.isEmpty())、set.retainAll(anotherSet) 全是原生支持。
立即学习“Java免费学习笔记(深入)”;
- 别踩坑:
Arrays.asList(arr)返回的是“假集合”——底层仍指向原数组,不支持add()/remove(),会抛UnsupportedOperationException - 初始化陷阱:想建空集合直接
new ArrayList();但new int[0]是合法空数组,new ArrayList(0)和new ArrayList()效果一样,都从默认容量10开始 - 线程安全差异:数组天然无并发问题(除非共享可变状态);集合多数非线程安全,多线程写
ArrayList必须加锁或换CopyOnWriteArrayList
int[100] 还是 ArrayList?关键看后续操作:只遍历读?数组更省;要动态增删、去重、排序?集合省心十倍。选型不是比语法,而是比“接下来你要对它做什么”。









