Appearance
ArrayList 为什么仍然是默认首选:扩容、随机访问和使用边界
很多人知道 ArrayList 底层是数组,也知道它会扩容,但真正到业务里选型时,还是容易被一句“LinkedList 增删快”带偏。
实际上,大多数普通业务场景里,ArrayList 依然是更稳的默认首选。
先说结论
先记住这几个判断:
- 大部分
List场景,优先ArrayList - 它的核心优势是随机访问快、遍历性能稳定
- 扩容有成本,但通常不是日常业务里的主要瓶颈
- 真正常见的问题,反而是误把它用在超大列表或频繁中间插入场景
一、ArrayList 的本质
ArrayList 底层是动态数组。
这意味着:
- 可以按下标快速访问
- 内存布局连续
- 遍历时更符合 CPU 缓存友好性
也正因为如此,它在很多常见场景里表现都很好:
- 分页结果集
- DTO 列表
- 查询返回集合
- 内存中批量处理结果
二、扩容到底意味着什么
ArrayList 的扩容不是“无代价变大”,而是:
- 分配更大的新数组
- 把旧数组内容复制过去
所以扩容本身确实会有成本。
但要注意:
- 扩容不是每次
add都发生 - 大多数业务列表规模并不大到需要过度焦虑扩容
如果你明确知道数据量大概是多少,可以提前设置容量,减少扩容次数:
java
List<String> list = new ArrayList<>(1024);三、为什么它通常比 LinkedList 更适合业务开发
因为很多真实业务操作其实都是:
- 顺序追加
- 遍历处理
- 按下标访问
而不是“拿着链表节点频繁局部插入删除”。
这时 ArrayList 往往更符合实际。
四、什么时候 ArrayList 不那么合适
1. 中间位置频繁插入删除
因为元素要搬移。
2. 列表极大且不断增长
这时要开始考虑:
- 是否应该分页处理
- 是否该流式处理
- 是否真的要一次全部加载进内存
3. 用它承载无上限缓存
这类问题最终很容易演变成内存上涨,而不是集合本身语法问题。
五、业务里最容易踩的坑
1. for 循环里频繁 remove
这很容易导致:
- 下标错位
- 性能下降
如果需要边遍历边删除,更建议用迭代器或先筛选再重建集合。
2. 把超大数据集一次查到内存里
问题不在 ArrayList,而在设计方式。
3. 明明已知容量,却一直默认空构造
如果这是个高频热点路径,预估容量通常会更稳一些。
一句话总结
ArrayList 的价值不只是“好用”,而是它恰好匹配了大多数业务列表的真实访问模式。
所以除非你非常明确地需要别的特性,否则把 ArrayList 当成 List 的默认首选,通常是对的。