最后更新:2026-11-01 · 基于第 1 次作答
结论:三者都是 List 接口实现,本质差异在底层结构——ArrayList/Vector 基于动态数组、LinkedList 基于双向链表,由此决定读写增删性能与线程安全边界。 关键词:动态数组扩容 1.5x · 双向链表指针 · synchronized 边界:链表 O(1) 增删的前提是已持有节点引用,否则定位仍 O(n);线程安全读多写少优先 CopyOnWriteArrayList。
核心考点定位:考察 Java 集合框架三种 List 实现的底层结构差异,以及从底层结构推导出的读写增删性能与线程安全边界;面试官想看到"从底层实现推能力",而不是背结论。
机制链(≥3 环):
Object[] elementData → 按下标 O(1) 随机访问;但中间插入/删除需搬运后续元素 → O(n)。grow()(默认 1.5 倍)→ 新建数组 + System.arraycopy 整体迁移 → 扩容成本随规模上升。prev/next 指针 → 增删只改指针 O(1);但定位任意节点仍需从首/尾遍历 → O(n)。synchronized 修饰方法 → 线程安全,但整方法加锁 → 并发读写串行化、吞吐低 → JDK 已标记过时,读多写少用 CopyOnWriteArrayList 替代。证据锚点:
Object[] elementData:ArrayList 底层数组grow() / newCapacity:扩容逻辑(1.5 倍)System.arraycopy:扩容/搬运时复制数组Node<E>(item/prev/next):LinkedList 节点addFirst/addLast:头尾 O(1) 增删synchronized:Vector 方法级锁CopyOnWriteArrayList:读多写少的线程安全替代modCount:fail-fast 迭代检测对比与权衡:
| 维度 | ArrayList | LinkedList | Vector |
|---|---|---|---|
| 底层结构 | 动态数组 | 双向链表 | 动态数组 |
| 随机访问 | O(1) | O(n) 遍历 | O(1) |
| 中间增删 | O(n) 搬运 | O(n) 定位 + O(1) 指针 | O(n) 搬运 |
| 头尾增删 | 尾部均摊 O(1) | O(1) | 尾部均摊 O(1) |
| 线程安全 | 否 | 否 | 方法级 synchronized |
| 扩容 | 1.5 倍 | 无 | 2 倍 |
常见误区:
CopyOnWriteArrayList → 为什么:Vector 的整方法 synchronized 全局锁,写并发吞吐低。适用边界:
CopyOnWriteArrayList;线程安全写多 → Collections.synchronizedList 或并发容器。HashMap 0.75 负载因子的设计取舍类比addFirst/addLast 直接改头尾哨兵节点指针,无需遍历modCount 变化,触发 ConcurrentModificationExceptionCopyOnWriteArrayList 的 fail-safe 迭代器区别【结论】 三者都是 List 接口实现,本质差异在底层结构:ArrayList/Vector 基于动态数组、LinkedList 基于双向链表,由此决定读写增删性能与线程安全。
【三点】
第一,随机访问:ArrayList/Vector 按下标 O(1),LinkedList 需 O(n) 遍历;所以"按位置查"用数组实现。
第二,增删:链表只改指针,数组要搬运后续元素;但链表增删前要先 O(n) 定位,所以"头尾频繁增删"才占优。
第三,线程安全与扩容:Vector 方法 synchronized、扩容 2 倍,已过时;ArrayList 扩容 1.5 倍且非线程安全;读多写少需要线程安全时用 CopyOnWriteArrayList。
【边界】 链表 O(1) 增删的前提是已持有节点引用,否则定位仍 O(n);线程安全按"读多写少"选 CopyOnWriteArrayList,写多时其整数组复制成本高,反而不划算。
题目:ArrayList、LinkedList 与 Vector 的区别?
难度:low
标签:java/collections, java/collections, general/knowledge, difficulty/low
评分:⭐⭐⭐⭐☆(4/5)
三者都是list集合,但是三者各有取舍,其中arraylist和linkedlist都是非线程安全的,而vector是线程安全的;
但是vector已经作废不推荐使用了,线程安全有对应需求的时候可以使用copyonwriteArraylist
arraylist和linkedlist的核心区别是底层实现,以及不同底层实现带来的不同能力;
arraylist是基于数组实现的,可以快速定位到指定位置,快速替换,快速读取,但是增加删除节点的时候成本较高,需要移动其他节点,并且扩容需要进行整体迁移
LinkedList是基于链表实现,可以快速增减头结点和尾节点,但是查找某个中间位置的时候需要遍历读取,但是在增加节点和删除节点的时候可以很快执行遍历到位置移动指针就可以实现
评分:⭐⭐⭐⭐☆(4/5)
优点:准确说出三者都是 List;Array/List 线程安全差异、Vector 已废弃建议 CopyOnWriteArrayList;底层实现(数组 vs 链表)与随之而来的读写增删差异讲得很清楚。
不足:漏了 Vector 的方法级 synchronized + 默认容量 10、扩容 2 倍;ArrayList 扩容 1.5 倍;LinkedList 是双向链表(含头尾哨兵);CopyOnWriteArrayList 适用场景(读多写少)未展开。
补充:补①Vector 的 synchronized + 2 倍扩容;②ArrayList 1.5 倍扩容与 System.arraycopy 迁移;③链表"增删快"的前提是已定位到节点。
完整讲解见上方「完整讲解(权威版)」