【LinkedList】| 深度剥析Java SE 源码合集Ⅰ
目录
- 一. 🦁 LinkedList介绍
- 二. 🦁 结构以及对应方法分析
- 2.1 结构组成
- 2.1.1 节点类
- 2.1.2 成员变量
- 2.2 方法实现
- 2.2.1 添加add(E e)方法
- 2.2.2 头尾添加元素
- Ⅰ addFirst(E e)
- Ⅱ addLast(E e)
- 2.2.3 查找get(int index)方法
- 2.2.4 删除remove()方法
- 三. 🦁 总结
一. 🦁 LinkedList介绍
LinkedList 底层用双向链表实现的存储。特点:查询效率低,增删效率高,线程不安全。
双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向前
一个节点和后一个节点。 所以,从双向链表中的任意一个节点开始,都可以很方便地找到所有节点。

今天来探索一下LinkedList的源码分析,以便更熟悉Java容器的结构,了解其是如何存储元素的。
探索环境:jdk 11 & idea 2020
二. 🦁 结构以及对应方法分析
2.1 结构组成
由源码可知,LinkedList 不仅继承了AbstractSequentialList,还实现了List,Deque等接口。所以LinkedList除了可以当做链表来操作外,它还可以当做栈、队列和双端队列来使用。

2.1.1 节点类
双向链表由节点类前后连接而成,所以源码中肯定存在该Node类。我们从源码中得知其节点类组成:
item:存储当前节点元素的信息
next:存储当前节点的下一个节点地址信息
prev:存储当前节点的前一个节点地址信息
private static class Node<E> {E item;Node<E> next;Node<E> prev;Node(Node<E> prev, E element, Node<E> next) {this.item = element;this.next = next;this.prev = prev;}}
2.1.2 成员变量
这里记录了LinkedList的节点数(size),头节点地址(first),尾节点(last)。
transient int size = 0;/*** Pointer to first node.*/transient Node<E> first;/*** Pointer to last node.*/transient Node<E> last;
2.2 方法实现
2.2.1 添加add(E e)方法

从这里可知,这个add() 方法调用了linkLast(e)方法,返回一个布尔值。现在我们来看看这个linkLast(e)方法:
/*** Links e as last element.*/void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;}
从这个方法来看,add()方法的插入是尾插法,将last这个成员变量赋值给l(即l指向最当前节点),新new一个节点变量newNode<>(l,e,null),并且将其前驱节点指向l,如果 l == null,则第一个节点是newNode;否则直接在当前节点l指向新节点newNode。(modCount是指修改次数)。

2.2.2 头尾添加元素
Ⅰ addFirst(E e)
我们可以看到这里直接调用了linkFirst(E e)方法。

/*** Links e as first element.*/private void linkFirst(E e) {final Node<E> f = first;final Node<E> newNode = new Node<>(null, e, f);first = newNode;if (f == null)last = newNode;elsef.prev = newNode;size++;modCount++;}
这里是运用了头插法,将节点插入链表头部,依旧f和前面的l一样,指向当前节点(第一个节点);然后new 一个新的Node<>(null,e,f),将新节点的后继节点指向当前节点。当前节点不为null的情况下,将当前节点的前驱节点指向新节点,这样一次插入完成。

Ⅱ addLast(E e)
尾插法同前面的add(E e)。
2.2.3 查找get(int index)方法

这里调用了两个方法,一个是 checkElementIndex(index),该方法是用来检查用户输入的下标是否存在,如果不合法的话则会抛出 **IndexOutOfBoundsException(outOfBoundsMsg(index))**异常,具体实现如图:


第二个方法是:

该方法很明显是用来返回获取对应下标元素的值,具体实现如下:
/*** Returns the (non-null) Node at the specified element index.*/Node<E> node(int index) {// assert isElementIndex(index);if (index < (size >> 1)) {Node<E> x = first;for (int i = 0; i < index; i++)x = x.next;return x;} else {Node<E> x = last;for (int i = size - 1; i > index; i--)x = x.prev;return x;}}
这个方法运用了一个技巧:如果index是小于一半LinkedList长度时,则从头节点开始遍历查找;相反如果index大于一半LinkedList长度时,则从尾节点开始查找,这也是双向链表的一个优点。
2.2.4 删除remove()方法

LinkedList的删除方法比较多,我们就来探索一个常用的remove(),由源码可知,这里调用了removeFirst()方法:
/*** Removes and returns the first element from this list.** @return the first element from this list* @throws NoSuchElementException if this list is empty*/public E removeFirst() {final Node<E> f = first;if (f == null)throw new NoSuchElementException();return unlinkFirst(f);}
这里定义了f——>头节点,如果头节点为空,说明f为空,则说该LinkedList没有任何元素,则返回一个NoSuchElementException()错误。否则调用了unlinkFirst(f)方法。
/*** Unlinks non-null first node f.*/private E unlinkFirst(Node<E> f) {// assert f == first && f != null;final E element = f.item;final Node<E> next = f.next;f.item = null;f.next = null; // help GCfirst = next;if (next == null)last = null;elsenext.prev = null;size--;modCount++;return element;}
这里先定义了一个next节点指向头节点的下一个节点,然后赋值头节点的元素和next指针为null(这里主要是减少GC垃圾回收的工作量,提高效率),然后让头节点的指针指向next节点,这样next节点则成为新的一个头节点。就删除了头节点啦,size–,返回element。
三. 🦁 总结
今天介绍了LinkedList源码剥析。分析了常用方法的源码结构组成,LinkedList的源码组成比较简单,只要对双向链表这一数据结构熟悉的话,阅读起源码还是非常轻松的,希望您喜欢,一键三连哦!🐇 😄 🐇
相关文章:
【LinkedList】| 深度剥析Java SE 源码合集Ⅰ
目录一. 🦁 LinkedList介绍二. 🦁 结构以及对应方法分析2.1 结构组成2.1.1 节点类2.1.2 成员变量2.2 方法实现2.2.1 添加add(E e)方法2.2.2 头尾添加元素Ⅰ addFirst(E e)Ⅱ addLast(E e)2.2.3 查找get(int index)方法2.2.4 删除remove()方法三. &#x…...
黑马程序员7
算数运算符重载 运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型 加号运算符 通过自己写函数,实现两个对象相加属性后返回新的对象 两种方式重载 成员函数方式重载 全局函数重载 上来 perso…...
Qt安装与使用经验分享;无.pro文件;无QTextCodec file;Qt小试;界面居中;无缝;更换Qt图标;更换Qt标题。
1、切换安装下载源 《Qt安装教程》先推荐一篇安装文章:《Qt安装教程》 Qt 5.15 之后已经不提供离线安装包了,就是那个 3.7G 的 exe 安装包。请看官方说明,所以只能用在线安装包。 1,下载在线安装包 QT 在线安装包链接ÿ…...
AAAI顶会行人重识别算法详解——Relation Network for Person Re-identification
1.论文整体框架概述 在行人重识别任务中,通常都是对整个输入数据进行特征提取,但是缺少了局部信息。能不能既考虑局部与整体信息,也同时加入他们的联系呢?这篇论文主要的思想就是局部信息和全局信息的融合。 整体流程如上图所示, 首先对整体进行特征提取, 通常采用…...
hadoop调优(二)
hadoop调优(二) 1 HDFS故障排除 1.1 NameNode故障处理 NameNode进程挂了并且存储数据丢失了,如何恢复NameNode? 如果NameNode进程挂掉并且数据丢失了,可以利用Secondary NameNode来恢复NameNode。Secondary NameNode主要用于备份NameNode…...
【基础算法】双指针---数组元素的目标和
🌹作者:云小逸 📝个人主页:云小逸的主页 📝Github:云小逸的Github 🤟motto:要敢于一个人默默的面对自己,强大自己才是核心。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前…...
Javascript借用原型对象继承父类型方法
借用原型对象继承父类型方法 目的: 儿子继承父类属性和方法,父类之后新增的方法不会被儿子继承。 前言: 先理解一个问题: Son.prototype Father.prototype; 这一操作相当于把Son的原型对象指向Father。 意味着Son的prototype的地址与Fa…...
你不会工作1年了连枚举都还不知道吧?
💗推荐阅读文章💗 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》🌺MySQL系列🌺👉2️⃣《MySQL系列教程》🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》…...
ks通过恶意低绩效来变相裁员(五)绩效申诉就是「小六自证吃了一碗凉粉」
目录 一、小六吃了一碗凉粉 二、给你差绩效 公司告诉你可以绩效申诉 1、公司的实际目的是啥 2、你一旦自证,就掉入了陷阱 三、谁主张谁举证——让公司证明它绩效考核的客观性和公平性 四、针对公司的流氓恶意绩效行为,还有其他招吗 五、当公司用各…...
一阶低通滤波介绍及simulink模型
一阶低通滤波 背景介绍 低通滤波是一种过滤方式,规定低频信号能正常通过,而超过设定临界值的高频信号则被阻隔、减弱。低通滤波可以简单的认为:设定一个频率点,当信号频率高于这个频率时不能通过,在数字信号中&#…...
三十三、MongoDB PHP 扩展
PHP 语言访问 MongoDB 数据库需要使用 mongo 扩展 mongo 扩展不是 PHP 官方内置的扩展,需要开发者自己手动安装和配置 本章我们将学习如何在 Linux、Window、Mac 平台上安装 mongo 扩展 Linux 上安装 PHP MongoDB 扩展 通过 pecl 来安装 在 Linux 系统上可以通…...
2D图像处理:九点标定_上(机械手轴线与法兰轴线重合)(附源码)
文章目录 1. 九点标定2. 九点标定流程2.1 机械手轴线与法兰轴线重合代码实现1. 九点标定 在2D视觉抓取项目中,如果想要让机械手准确的抓取到工件,前提是需要知道机械手应该移动到哪里(位姿)。而移动到哪里(位姿)的获取就需要对相机和机械手进行标定。因此,九点标定(2D视…...
2023最新C++面经(一):vector内存预分配,左值引用和右值引用,move语义
文章目录零、前言一、在C中,往vector插入1000个数字,怎么做能保证性能最高二、在vector中对10000个数字删除偶数位置的数,怎么做保证性能较高三、malloc用delete会出现什么问题四、weak_ptr解决的是什么问题,lock返回的对象可以直接使用吗五、…...
【C语言经典例题】调整数组使奇数全部都位于偶数前面
目录 一、题目要求 二、解题思路 分步解析 从前往后找 从后往前找 交换 三、完整代码演示 一、题目要求 输入一个整数数组,实现一个函数, 来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分, 所有偶数位于数组的后半…...
C++经典20题型,满满知识,看这一篇就够了(含答案)
今天找了20道c的经典题型,看这一篇就够了,全是干货 目录 1、题目:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总…...
卷积神经网络CNN之ZF Net网络模型详解(理论篇)
1.背景 2. ZF Net模型结构 3. 改进优缺点 一、背景 ZF Net是用作者的名字命名的,Matthew D.Zeiler 和 Rob Fergus (纽约大学),2013年撰写的论文; 论文原网址https://arxiv.org/abs/1311.2901 论文名:Vis…...
Vue 3.0 响应性 基础 【Vue3 从零开始】
#声明响应式状态 要为 JavaScript 对象创建响应式状态,可以使用 reactive 方法: import { reactive } from vue// 响应式状态const state reactive({count: 0}) reactive 相当于 Vue 2.x 中的 Vue.observable() API ,为避免与 RxJS 中的 ob…...
flex布局方式让最后一个(或第二个...n)元素居右显示
<div class"round"> <div class"income">收入</div> <div class"center"> <img style"width: 12px" src"../../img/big/up.png"> </div> <div class"rg"> <span cl…...
【Python语言基础】——Python MySQL Order By
Python语言基础——Python MySQL Order By 文章目录 Python语言基础——Python MySQL Order By一、Python MySQL Order By一、Python MySQL Order By 结果排序 请使用 ORDER BY 语句按升序或降序对结果进行排序。 ORDER BY 关键字默认按升序对结果进行排序。若要按降序对结果进…...
自然数学的哲学原理--复数理论的扩展
自然数学的哲学原理--复数理论的扩展 2023-03-05 10:27:12 自然数学的哲学原理--复数理论的扩展 一维:线,实数 二维:平面 三维:立体 四维:相对论时空 复数,以一个数对形式表示,实现了复平面的…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
Xela矩阵三轴触觉传感器的工作原理解析与应用场景
Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知,帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量,能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度,还为机器人、医疗设备和制造业的智…...
