LinkedList适合首尾插入删除和用作栈/队列,因底层是双向链表;不适合随机访问或索引查找,get()需遍历节点,时间复杂度O(n),而ArrayList为O(1)。

LinkedList在Java中适合哪些操作
LinkedList适合频繁在列表首尾进行插入和删除的操作,不适合随机访问或按索引查找。它的底层是双向链表,没有连续内存地址,所以get(int index)需要从头或尾遍历节点,时间复杂度为O(n)。
- ✅ 高频使用
addFirst()、addLast()、removeFirst()、removeLast()时性能优于ArrayList - ✅ 用作栈(
push()/pop())或队列(offer()/poll())非常自然,因为这些方法都直接映射到链表头尾操作 - ❌ 频繁调用
get(i)或set(i, e)会明显拖慢性能,尤其当列表较大时 - ❌ 迭代中间元素(比如for循环用索引遍历)不如用增强for或迭代器高效
为什么LinkedList的get()比ArrayList慢
因为LinkedList.get(int index)内部会先判断索引靠近头部还是尾部,再决定从first还是last开始遍历,但无论如何都要跳过最多n/2个节点。而ArrayList直接通过数组下标访问,是O(1)。
看这个对比:
LinkedListlist = new LinkedList<>(); for (int i = 0; i < 10000; i++) list.add("item" + i); String s = list.get(9999); // 实际要遍历约5000个节点
如果业务逻辑中存在类似list.get(i)在循环里反复调用,即使i变化不大,也建议改用Iterator或换成ArrayList。
立即学习“Java免费学习笔记(深入)”;
LinkedList作为Deque使用的注意事项
LinkedList实现了Deque接口,所以它能天然支持双端队列语义。但要注意:它不是线程安全的,多线程环境下必须手动同步,或者改用ConcurrentLinkedDeque。
-
add()和offer()都往尾部加,但add()失败时抛IllegalStateException,offer()返回false -
remove()和poll()都从头部取,但remove()为空时抛NoSuchElementException,poll()返回null - 用
push()/pop()模拟栈时,实际操作的是头部,和addFirst()/removeFirst()等价
内存开销和实际选型建议
每个Node对象除了存数据,还要存prev和next引用,在32位JVM上额外占8字节,64位(开启指针压缩)也至少占16字节。这意味着同样存1万个字符串,LinkedList比ArrayList多占用数万字节内存。
- 元素总数小(
- 需要随机访问、迭代密集、内存敏感 → 优先ArrayList
- 明确要当栈/队列用,且不关心线程安全 → LinkedList语义清晰,代码可读性好
- 高并发场景下仍需双端操作 → 别硬套LinkedList,直接上
ConcurrentLinkedDeque
for (int i = 0; i 的人,得先想清楚自己到底在操作什么。










