addfirst() 是最优解,因其时间复杂度稳定 o(1),无需遍历、索引计算或数组复制,仅通过新建节点、更新指针四步完成头插,比 add(0,e) 和 arraylist 的 add(0,e) 更高效。

直接用 addFirst() 方法,时间复杂度稳定 O(1),不搬移元素、不遍历定位。
为什么 addFirst() 是最优解
LinkedList 是双向链表,addFirst() 底层只做四件事:新建节点、把新节点 next 指向原头节点、更新原头节点的 prev 指针、将 first 引用指向新节点。全程无循环、无索引计算、无数组复制。
- 比
add(0, e)快 10%–20%,后者需调用node(0)做额外判断 - 比 ArrayList 的
add(0, e)快得多——后者是 O(n) 数组整体右移 - 插入后新元素立即成为索引 0,但别用
get(0)读取,它会遍历
正确写法与常见错误
调用极其简单,传入元素即可,返回 void:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- ✅ 正确:
list.addFirst("newHead"); - ❌ 编译失败:
list.addFirst(0, "x")(方法不存在) - ❌ 编译失败:
boolean ok = list.addFirst("x")(返回类型是 void) - ⚠️ 能运行但低效:
list.add(0, "x")——触发内部遍历,非真正头插
配套操作建议(保持高效)
单靠 addFirst() 不够,整个使用链要匹配链表特性:
- 查头元素用
peekFirst()(空时返回 null)或getFirst()(空时抛异常),别用get(0) - 删头元素用
pollFirst()或removeFirst(),语义清晰且 O(1) - 若逻辑本质是双端队列(如消息前置、解析缓存),优先声明为
Deque<e></e>:Deque<string> dq = new LinkedList();</string>dq.offerFirst("urgent"); - 多线程场景必须加锁:
synchronized(list) { list.addFirst(e); },别用 Collections.synchronizedList
什么情况反而不该用
不是所有“要插在开头”的场景都适合 LinkedList:
- 后续大量按索引随机访问(如频繁
get(i)),ArrayList 更快 - 数据量小、插入频次低,内存开销(每个节点多两个引用)可能得不偿失
- 需要 trimToSize、ensureCapacity 等 ArrayList 特有控制能力
- 实际是逆序构建+正序遍历,可考虑先用 ArrayList 收集再
Collections.reverse()
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










