Java LinkedList解密

一、LinkedList最底层的原理

        LinkedList其实底层是链表:

        当初始化的时候,会将链表这个节点的值、prev指针和next指针初始化。

二、LinkedList初始化

 

        无参构造并没有做什么。有参构造会先调用无参构造,然后调用addAll方法将链表的节点都初始化:

二、增加元素

2.1 add(object)

        调用了linkLast方法。就是在尾部添加元素

2.1.1 linkLast

 

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++; // 增加链表的元素个数
}

         常见的双向链表插入元素的逻辑。不得不说,jdk的代码还是很简洁的。这里画个图示:

        当插入空链表时:

        当链表中有一个元素时:

 

二、删除元素 

2.1 remove() 

 

        无参的remove调用的是removeFirst(),可以看出是从头开始删的。这个函数放在后面讲。

2.2 remove(object)

 

        删除指定的元素,这个删除逻辑和ArrayList一样,有兴趣的可以看看我讲解的ArrayList源码:Java ArrayList解密-CSDN博客

public boolean remove(Object o) {if (o == null) { // 如果要删除的元素为 nullfor (Node<E> x = first; x != null; x = x.next) { // 遍历链表if (x.item == null) { // 如果节点的元素为 nullunlink(x); // 删除节点return true; // 返回 true 表示删除成功}}} else { // 如果要删除的元素不为 nullfor (Node<E> x = first; x != null; x = x.next) { // 遍历链表if (o.equals(x.item)) { // 如果节点的元素等于要删除的元素unlink(x); // 删除节点return true; // 返回 true 表示删除成功}}}return false; // 如果链表中不包含要删除的元素,则返回 false 表示删除失败
}

 2.2.1 unlink()

        顾名思义,其实就是取消这个节点和链表的连接关系。他更新要删除的这个节点的prev和next指针,并将当前节点置为null便于GC

 

E unlink(Node<E> x) {final E element = x.item; // 获取要删除节点的元素final Node<E> next = x.next; // 获取要删除节点的下一个节点final Node<E> prev = x.prev; // 获取要删除节点的上一个节点if (prev == null) { // 如果要删除节点是第一个节点first = next; // 将链表的头节点设置为要删除节点的下一个节点} else {prev.next = next; // 将要删除节点的上一个节点指向要删除节点的下一个节点x.prev = null; // 将要删除节点的上一个节点设置为空}if (next == null) { // 如果要删除节点是最后一个节点last = prev; // 将链表的尾节点设置为要删除节点的上一个节点} else {next.prev = prev; // 将要删除节点的下一个节点指向要删除节点的上一个节点x.next = null; // 将要删除节点的下一个节点设置为空}x.item = null; // 将要删除节点的元素设置为空size--; // 减少链表的元素个数return element; // 返回被删除节点的元素
}

2.3 removeFirst() 

 

        先判断链表内有没有元素,然后调用unlinkFist()方法删除

2.3.1 unlinkFist()

 

private E unlinkFirst(Node<E> f) {final E element = f.item; // 获取要删除的节点的元素final Node<E> next = f.next; // 获取要删除的节点的下一个节点f.item = null; // 将要删除的节点的元素设置为 nullf.next = null; // 将要删除的节点的下一个节点设置为 nullfirst = next; // 将链表的头节点设置为要删除的节点的下一个节点if (next == null) // 如果链表只有一个节点last = null; // 将链表的尾节点设置为 nullelsenext.prev = null; // 将要删除节点的下一个节点的前驱设置为 nullsize--; // 减少链表的大小return element; // 返回被删除节点的元素
}

        说白了就是把first指针指向的节点去掉,然后将first指针指向下一个节点,再将当前first的prev置为null

2.4 removeLast() 

        逻辑上和removeFirst()差不多,就不多赘述了。

 

三、修改

3.1 set(index, object)

public E set(int index, E element) {checkElementIndex(index); // 检查索引是否超出范围Node<E> x = node(index); // 获取要替换的节点E oldVal = x.item; // 获取要替换节点的元素x.item = element; // 将要替换的节点的元素设置为指定元素return oldVal; // 返回替换前的元素
}

3.1.1 node方法

        找到索引位置的元素。

        比较有意思的点是,他会判断索引位置在链表前半段还是后半段。如果在前半段,就从前面遍历链表;如果在后半段,就从后面遍历链表 

 

Node<E> node(int 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; // 返回指定位置的节点}
}

四、查找元素 

4.1 get(index) 

        查找索引处元素 

 

        检查索引后,调用node方法找到元素,node方法在前面讲过了,这里略去。

4.2 indexOf(object) 

        查找指定元素

 

         逻辑和ArrayList的indexOf一致,都是直接遍历

五、和ArrayList的比较 

        敬请期待下一章 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/593877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数值分析】数值积分,复合中点,复合梯形,复合Simpson,matlab实现

数值积分与数值微分 2023年11月29日 #analysis 文章目录 数值积分与数值微分1. 求积公式与代数精度2. 几个常用积分公式及其复合积分公式2.1 中点公式2.2 梯形公式2.3 抛物型公式/Simpson公式2.4 复合中点公式2.5 复合梯形公式2.6 复合Simpson公式 1. 求积公式与代数精度 求积…

什么是高防 IP?哪些行业适合用高防 IP?

在数字化浪潮席卷全球的今天&#xff0c;网络安全问题日益凸显。有听说过“高防 IP”这个名词吗&#xff1f;它究竟是什么东西&#xff0c;又能在哪些领域大显身手呢&#xff1f; 一、什么是高防 IP&#xff1f; 高防 IP&#xff0c;顾名思义&#xff0c;就是具备高级防护能力…

1_并发编程_线程的基本概念和线程终止及线程问题排查

1.线程的运行状态 在Java中&#xff0c;线程的状态一共是6种状态&#xff0c;分别是 NEW&#xff1a;初始状态&#xff0c;线程被构建&#xff0c;但是还没有调用start方法 RUNNABLED&#xff1a;运行状态&#xff0c;JAVA线程把操作系统中的就绪和运行两种状态统一称为“运行…

【C程序设计】C判断

判断结构要求程序员指定一个或多个要评估或测试的条件&#xff0c;以及条件为真时要执行的语句&#xff08;必需的&#xff09;和条件为假时要执行的语句&#xff08;可选的&#xff09;。 C 语言把任何非零和非空的值假定为 true&#xff0c;把零或 null 假定为 false。 下面…

.mallox勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

引言&#xff1a; 随着技术的不断发展&#xff0c;网络空间也不可避免地面临着各种威胁&#xff0c;其中之一就是勒索病毒&#xff0c;而.mallox是近期引起关注的一种恶意软件。本文将介绍.mallox勒索病毒&#xff0c;以及如何有效地恢复被其加密的数据文件&#xff0c;并提供…

ros2激光雷达<gazebo>仿真资料

Lidar sensor激光雷达传感器 We dont want our robot to touch the wall at all because this may cause some damage, so instead of the contact sensor we can use the Lidar. Lidar is an acronym for "light detection and ranging". This sensor can help us …

OpenFeign相关面试题及答案(2024)

1、什么是OpenFeign&#xff0c;它如何简化远程服务调用&#xff1f; OpenFeign是一个声明式的Web服务客户端&#xff0c;它使得编写HTTP客户端变得更加容易。它属于Spring Cloud Netflix项目的一部分&#xff0c;可以与Spring Boot应用轻松集成。通过使用OpenFeign&#xff0…

Lingo 17安装包下载及安装教程

Lingo 17下载链接&#xff1a;https://docs.qq.com/doc/DUndEVXd4WVVweGFR 1.鼠标右键解压到“Lingo 17.0” 2.双击打开【Setup】文件夹 3.选中Lingo 17.0&#xff0c;鼠标右键选择“以管理员身份运行” 4.点击“Next” 5.选中I accept the terms in the license agreement&…

go语言`json:“-“`标签的含义

json:"-" 是 Go 语言中的一个标签&#xff08;tag&#xff09;&#xff0c;用于指示编码和解码 JSON 时忽略对应的字段。 在 Go 中&#xff0c;结构体的字段可以通过添加标签来指定其在编码为 JSON 字符串或解码时的行为。json:"-" 标签的作用是告诉编码和…

第四篇 行为型设计模式 - 灵活定义对象间交互

第四篇&#xff1a;行为型设计模式 - 灵活定义对象间交互 行为型设计模式关注对象之间的交互和职责分配&#xff0c;旨在定义对象间的高效、灵活的通信机制。以下是十一种常见行为型设计模式的详解及其应用场景。 1. 策略模式详解及其应用场景 详解&#xff1a; 策略模式定义…

贪心算法part05 435无重叠区间

435无重叠区间 763 划分字母区间 56合并区间

javascript中location对象的属性与方法

前言 本章介绍js中的location中的属性和方法。 文章目录 前言什么是location为什么要用locationlocation对象属性location对象方法总结 什么是location 在JavaScript中&#xff0c;location 是一个包含当前页面的URL信息的对象。它允许你获取和操作当前页面的URL&#xff0c;比…

速通C语言第十二站 文件操作

系列文章目录 速通C语言系列 速通C语言第一站 一篇博客带你初识C语言 http://t.csdn.cn/N57xl 速通C语言第二站 一篇博客带你搞定分支循环 http://t.csdn.cn/Uwn7W 速通C语言第三站 一篇博客带你搞定函数 http://t.csdn.cn/bfrUM 速通C语言第四站 一篇博客带…

QML 项目中使用 Qt Design Studio 生成的UI界面

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 今天来和大家聊一下 Qt Design Studio 这个软件。这个软件的主要功能是用来快速完成 UI 界面&#xff0c;就和 widget 中的 desig…

Vue.js 中使用 Watch 选项实现动态问题判断与展示答案

组件结构 以下是组件的基本结构&#xff1a; <template><div><!-- 输入框&#xff0c;用于输入问题 --><p>提出一个是/否问题&#xff1a;<input v-model"question" :disabled"loading" /></p><!-- 显示答案 --&…

栈实现后缀表达式的计算

后缀表达式计算 过程分析 中缀表达式 &#xff08;15&#xff09;*3 > 后缀表达式 153* (可参考这篇文章&#xff1a;中缀转后缀) 第一步&#xff1a;我们从左至右扫描 后缀表达式(已经存放在一个字符数组中)&#xff0c;遇到第一个数字字符 ‘1’ 放入栈中第二步&#xf…

市场复盘总结 20240103

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整 昨日回顾: 方法一:指标选股 select * from dbo.ResultAll where 入选类型 like %指标选股% and 入选日期=20240103;方法二:趋势选股法 1、最低价持续3日上涨 2、均价…

新的一年,新的征程,35岁,再出发!!

2024&#xff0c;迈入新的征程&#xff01;35岁是人生的一个重要阶段&#xff0c;是积累经验、提升自我、迎接挑战的黄金时期&#xff0c;在接下来的日子&#xff1a; 设定目标&#xff1a;明确自己的长期和短期目标&#xff0c;确保自己始终朝着正确的方向前进。目标可以是职…

jmeter线程组

特点&#xff1a;模拟用户&#xff0c;支持多用户操作&#xff1b;可以串行也可以并行 分类&#xff1a; setup线程组&#xff1a;初始化 类似于 unittest中的setupclass 普通线程组&#xff1a;字面意思 teardown线程组&#xff1a;环境恢复&#xff0c;后置处理

机器视觉系统选型-选型-总结

一&#xff1a;明确需求 需求&#xff1a;镜面材质上的划痕检测&#xff0c;传送线上运动过程中拍照&#xff0c;无景深要求&#xff0c;传送线速度0.8m/s&#xff0c;产品间隔50mm 产品大小&#xff1a;100*80mm 工作距离限制&#xff1a;≤ 300mm 最小划痕宽度&#xff1a;0.…