news 2026/6/18 18:36:56

数据结构(Java版)第八期:LinkedList与链表(三)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
数据结构(Java版)第八期:LinkedList与链表(三)

数据结构第八期:LinkedList 与链表(Java 版)

这是 Java 中最常被问到的数据结构之一,也是面试、笔试、日常开发中最容易踩坑的地方。

下面从原理 → 源码 → 常见操作 → 面试高频题 → 实际使用建议完整梳理一遍。

1. LinkedList 在 Java 中的真实身份

publicclassLinkedList<E>extendsAbstractSequentialList<E>implementsList<E>,Deque<E>,Cloneable,java.io.Serializable

一句话总结:
LinkedList 同时实现了 List 和 Deque 接口,所以它既是“双向链表”,也是“双端队列”

最关键的两点:

  • 底层是双向链表(doubly-linked list)
  • 没有像 ArrayList 那样的连续数组存储

2. 核心内部结构(JDK 8/11/17/21 一致)

privatestaticclassNode<E>{Eitem;// 元素本身Node<E>next;// 后继指针Node<E>prev;// 前驱指针}

三个重要成员变量:

transientintsize=0;// 元素个数transientNode<E>first;// 头节点(first)transientNode<E>last;// 尾节点(last)

最经典的图示(双向链表)

null ← prev [prev | item | next] ↔ [prev | item | next] ↔ [prev | item | next] next → null ↑ first ↑ last

3. 常用操作的时间复杂度(面试必背)

操作时间复杂度说明
get(index)O(n)从头/尾选近的一端开始遍历
set(index, element)O(n)同上,需要找到第 index 个节点
addFirst / addLastO(1)直接操作 first/last 指针
add(index, element)O(n)找到位置 + 修改指针(最坏 O(n))
removeFirst / removeLastO(1)直接操作 first/last
remove(Object o)O(n)需要线性查找 + 修改指针
remove(index)O(n)找到节点 + 修改前后指针
contains(Object o)O(n)线性查找
size() / isEmpty()O(1)直接返回 size 字段
iterator() / listIterator()O(1)返回链表迭代器(支持双向遍历)

一句话总结
凡是涉及“按索引操作”的几乎都是 O(n),凡是“头尾操作”的都是 O(1)

4.LinkedList 作为 Deque(双端队列)的常用方法

LinkedList 实现了 Deque 接口,所以可以用它当队列双端队列用。

场景首选方法(推荐)等价方法(不推荐抛异常版)说明
入队(尾)offerLast(e) / addLast(e)add(e)尾插
出队(头)pollFirst()removeFirst()头出,空返回 null
入栈(头)push(e)addFirst(e)头插(栈顶)
出栈(头)pop()removeFirst()头出(栈顶)
取头peekFirst()getFirst()看头元素,不删除
取尾peekLast()getLast()看尾元素,不删除

面试最爱问的写法对比

// 当栈用(LIFO)LinkedList<Integer>stack=newLinkedList<>();stack.push(1);// 入栈stack.push(2);stack.pop();// 出栈 → 2
// 当队列用(FIFO)LinkedList<Integer>queue=newLinkedList<>();queue.offer(1);// 入队queue.offer(2);queue.poll();// 出队 → 1

5. 源码中最容易被问到的几个点

  1. addFirst / addLast 的实现(O(1))
publicvoidaddFirst(Ee){linkFirst(e);}privatevoidlinkFirst(Ee){finalNode<E>f=first;finalNode<E>newNode=newNode<>(null,e,f);first=newNode;if(f==null)last=newNode;elsef.prev=newNode;size++;modCount++;}
  1. get(int index) 为何慢(O(n))
publicEget(intindex){checkElementIndex(index);returnnode(index).item;}Node<E>node(intindex){// assert isElementIndex(index);if(index<(size>>1)){// 前半段从头开始找Node<E>x=first;for(inti=0;i<index;i++)x=x.next;returnx;}else{// 后半段从尾开始找(关键优化!)Node<E>x=last;for(inti=size-1;i>index;i--)x=x.prev;returnx;}}
  1. 为什么 LinkedList 实现了 RandomAccess 接口?

答案它其实没有实现 RandomAccess
(ArrayList 实现了,LinkedList 没有)

publicclassArrayList<E>...implementsRandomAccess...publicclassLinkedList<E>...// 没有 implements RandomAccess

这也是为什么List遍历时推荐用for-eachiterator,而不是get(i)循环的原因。

6. 面试高频题 TOP 10(带答案)

  1. LinkedList 是线程安全的吗?
    否。所有方法都没有 synchronized。

  2. LinkedList 和 ArrayList 的区别?(必问)

项目ArrayListLinkedList
底层结构动态数组双向链表
随机访问O(1)O(n)
插入/删除(头尾)O(n)(需移动元素)O(1)
插入/删除(中间)O(n)O(n)(查找)+O(1)(修改指针)
内存开销较小(连续)较大(每个节点有 prev/next)
适用场景读多写少、频繁随机访问频繁头尾增删、队列/栈
  1. LinkedList 可以当栈和队列用吗?怎么用?
    可以。推荐用 push/pop 当栈,offer/poll 当队列。

  2. 为什么 LinkedList 没有 capacity(容量)概念?
    因为是链表,不需要预分配空间。

  3. Iterator 和 ListIterator 的区别?
    LinkedList 的 iterator() 是单向的,listIterator() 是双向的,支持 add/set/remove。

  4. modCount 有什么作用?
    快速失败机制(fail-fast)。结构修改时 modCount++,迭代器发现 modCount 变化就抛 ConcurrentModificationException。

  5. ConcurrentLinkedQueue 和 LinkedList 的区别?
    前者是线程安全的无界队列(CAS),后者非线程安全。

  6. 为什么不建议用 LinkedList 做大数据量的随机访问?
    每次 get(i) 都要从头/尾遍历,时间复杂度 O(n),n 很大时很慢。

  7. LinkedList 的 subList() 返回的是什么?
    SubList 内部类,是原链表的视图,修改会影响原链表(非深拷贝)。

  8. 实际项目中什么时候选 LinkedList?

7. 2026 年真实使用建议

需要我手写一个双向链表的完整实现(不依赖 LinkedList)吗?
或者想看 LinkedList 在 LeetCode 哪些题中是最佳解?
随时告诉我~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 22:36:00

【大数据毕设全套源码+文档】基于Django+hadoop的零食销售大数据分析及可视化系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/16 23:39:07

升级你的AI绘画工具箱:Z-Image-Turbo优势全解析

升级你的AI绘画工具箱&#xff1a;Z-Image-Turbo优势全解析 1. 为什么你需要重新认识“文生图”这件事 你有没有过这样的体验&#xff1a; 输入一段精心打磨的提示词&#xff0c;点击生成&#xff0c;然后盯着进度条数秒、十几秒、甚至半分钟——最后出来的图&#xff0c;细节…

作者头像 李华
网站建设 2026/6/10 7:01:34

Z-Image-Turbo快速上手:三步完成文生图服务部署实战

Z-Image-Turbo快速上手&#xff1a;三步完成文生图服务部署实战 1. 为什么Z-Image-Turbo值得你花5分钟试试&#xff1f; 你是不是也遇到过这些情况&#xff1a;想用AI画张图&#xff0c;结果等了两分钟才出第一帧&#xff1b;好不容易跑起来&#xff0c;发现中文提示词根本不…

作者头像 李华
网站建设 2026/6/15 20:01:27

cv_unet_image-matting Alpha阈值设置多少合适?多场景实战解析

cv_unet_image-matting Alpha阈值设置多少合适&#xff1f;多场景实战解析 1. 为什么Alpha阈值是抠图效果的关键开关&#xff1f; 你可能已经发现&#xff0c;在cv_unet_image-matting的WebUI里&#xff0c;「Alpha阈值」这个参数看起来平平无奇&#xff0c;就一个0-50的滑块…

作者头像 李华
网站建设 2026/6/17 1:04:35

硬核实战:YOLOv8-Pose在RK3588上的ONNX转换、量化加速与高效部署指南

文末含资料链接和视频讲解! 文章目录 一、模型导出ONNX结构对比:为何要“化繁为简”? 🤔 二、YOLOv8-Pose导出ONNX的代码修改 💻 1. 步骤一:修改`ultralytics/nn/modules/head.py` 中的 `Detect` 模块 一、模型导出ONNX结构对比:为何要“化繁为简”? 🤔 二、YOLOv…

作者头像 李华
网站建设 2026/6/17 0:57:26

Qwen3-0.6B推理延迟高?GPU算力优化实战教程提升响应速度

Qwen3-0.6B推理延迟高&#xff1f;GPU算力优化实战教程提升响应速度 1. 为什么Qwen3-0.6B在实际调用中会“卡一下”&#xff1f; 你刚把Qwen3-0.6B镜像拉起来&#xff0c;打开Jupyter Notebook&#xff0c;粘贴几行LangChain代码&#xff0c;满怀期待地敲下chat_model.invoke…

作者头像 李华