linkedlist 插入/删除快是因为其双向链表结构支持 o(1) 局部操作,但前提是避免索引访问,优先使用头尾方法或迭代器;随机访问(get)为 o(n),滥用会抵消优势。

Java 中的 LinkedList 本身就是基于双向链表实现的,天然适合频繁的插入和删除操作——关键在于**避免使用索引访问,优先使用头尾或迭代器操作**。
为什么 LinkedList 插入/删除快?
LinkedList 内部是双向链表节点(Node),每个节点持有前驱(prev)和后继(next)引用。只要拿到目标节点的引用,插入或删除都是 O(1) 操作——不需要像数组那样移动元素。
⚠️ 注意:这不等于“用 get(int index) 再插入就快”。get(i) 是 O(n) 的遍历查找,会抵消链表优势。
高效插入的正确姿势
优先使用头尾或基于已有节点/迭代器的操作:
-
头插:用
addFirst(e)或push(e)—— O(1) -
尾插:用
addLast(e)或add(e)(默认即尾插)—— O(1) -
指定位置前插入:先用
listIterator(index)获取迭代器,再调add(e)—— O(n) 查找 + O(1) 插入,比add(index, e)更可控 -
在已知节点后插入:无法直接暴露 Node,但可通过
ListIterator遍历时用add()插入到当前游标前 —— 实际仍是 O(1) 局部操作
高效删除的正确姿势
同样避开随机索引删除:
-
删头:用
removeFirst()或pop()—— O(1) -
删尾:用
removeLast()—— O(1) -
删指定元素(首次出现):用
remove(Object o)—— O(n) 查找 + O(1) 删除;若已知位置,应改用迭代器 -
用迭代器安全删除:遍历时调
iterator.remove()—— O(1),且避免ConcurrentModificationException
实际建议与避坑
真正发挥 LinkedList 性能,要配合使用场景设计:
- 当需要频繁在开头/结尾增删(如栈、队列、LRU 缓存),直接用
addFirst/removeLast等方法 - 若需按位置操作,尽量复用迭代器,避免反复调
get(i) - 不要把它当“更快的 ArrayList”来用——随机访问性能差(O(n)),索引操作多时反而不如 ArrayList
- 内存开销略大(每个元素额外两个引用),小数据量或只读场景没必要强上 LinkedList
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











