LinkedList适合头尾频繁增删,时间复杂度O(1),适用于栈、队列、滑动窗口等;不适合随机访问,get(i)为O(n);内存开销大,线程不安全,高并发建议用ConcurrentLinkedQueue。

LinkedList适合需要频繁在列表两端增删元素的场景,不适合随机访问或大量按索引查找。
适合在头尾频繁插入和删除
LinkedList底层是双向链表,头插(addFirst)、尾插(addLast)、头删(removeFirst)、尾删(removeLast)都是O(1)时间复杂度。比如实现栈、队列、滑动窗口头部维护等。
- 用offerFirst / pollFirst模拟栈操作
- 用offerLast / pollFirst模拟FIFO队列(比ArrayList更自然)
- 处理日志缓冲区、最近N条记录缓存时,新数据加尾、旧数据删头非常高效
不适合按索引随机访问
因为没有连续内存地址,每次调用get(i)都要从头或尾开始遍历节点,平均耗时O(n/2)。若代码中出现大量list.get(i)循环,性能会明显劣于ArrayList。
- 遍历时优先用迭代器(for (E e : list) 或 iterator()),避免下标访问
- 如果业务逻辑强依赖快速定位(如分页查第1000个元素),应换用ArrayList或考虑其他结构(如ArrayDeque不支持随机访问但更快)
内存开销比ArrayList大
每个元素额外存储前驱和后继两个引用(8字节×2,在64位JVM压缩指针开启时可能为4字节×2),而ArrayList只存对象引用数组。当元素数量大、对象本身较小时,LinkedList的空间利用率明显偏低。
立即学习“Java免费学习笔记(深入)”;
- 存上万个小整数(Integer)时,LinkedList可能多占30%~50%内存
- 高吞吐、低延迟服务中,GC压力可能因此上升,需结合堆分析工具观察
线程不安全,但可配合Collections.synchronizedList
LinkedList本身未做同步,多线程直接读写会出错。若需线程安全且保留链表特性,可用Collections.synchronizedList(new LinkedList()),但注意它只保证单个方法原子性,复合操作仍需手动同步。
- 例如“检查是否为空再取首元素”必须加synchronized块包裹
- 更高并发场景建议用ConcurrentLinkedQueue替代——它是无锁链表队列,更适合生产环境










