LinkedList中查询(contains)和删除(remove)源码分析

一、contains源码分析

本文分析双向链表LinkedList的查询操作源码实现。jdk中源程序中,LinkedList的查询操作,通过contains(Object o)函数实现。具体见下面两部分程序:

public boolean contains(Object o) {return indexOf(o) != -1;
}

public int indexOf(Object o) {int index = 0;if (o == null) {for (Node<E> x = first; x != null; x = x.next) {if (x.item == null)return index;index++;}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item))return index;index++;}}return -1;
}

indexOf函数查询对象o在链表中的索引位置。

源码首先将元素为null的情形单独判读剥离,个人分析,应该是如果不单独分析,null元素在下边的for循环中,不能执行o.equals操作(编译器输入null.,会自动将已有输入替换为NullPointerException.,提示空指针异常)。

由于链表不同于数组,在内存中并非连续存储,因此访问某个元素需要遍历。源程序中使用for循环进行遍历。index表示链表元素索引,初值为0。

1、针对空元素(null)的情况,用for循环遍历,查找元素为null的节点,并返回索引index。for循环初始条件为头指针(无元素),判断条件为节点不为null,自增表达式为x重赋值为下个节点(利用节点x的next指针实现,在java中next为node对象的属性成员)。每次自增,index+1。
2、针对非空元素,遍历操作同上。函数结束的判断条件变为o.equals(x.item),这里equals方法为Object超类的方法,程序中元素类型非Object也可调用。

两种情形下,链表遍历完毕(仍为return),表明该元素o在链表中不存在,因此返回-1。

二、remove源码对比

通过查阅,发现remove方法和contains方法的源码实现非常相似,列出如下:

/*** Removes the first occurrence of the specified element from this list, * if it is present.  If this list does not contain the element, it is* unchanged. * @param o element to be removed from this list, if present* @return {@code true} if this list contained the specified element*/public boolean remove(Object o) {if (o == null) {for (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) {unlink(x);return true;}}}return false;
}

对比发现,和contains类似,remove操作首先也是查找Object o是否存在与表中。空节点元素和非空节点的循环判断基本相同,在找到Object o后,区别与contains的返回索引,remove需要删除节点link(LinkedList的删除需要对next链进行重配置引用)。

删除节点的方法unlink的源码如下:

//Unlinks non-null node x. 
E unlink(Node<E> x) {// assert x != null;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--;modCount++;  //注:已从结构上修改此列表的次数。AbstractList属性return element;
}

分析:
删除节点程序中,需要考虑节点在链表中的不同位置,进行不同的操作。

1、节点于链表首端

clipboard.png

此时,特殊操作是需要将first指针(引用)指向其后的节点。

first = next;

2、节点于链表尾端

clipboard.png

此时,需要将上一个节点的next指针指向null,即上个节点称为尾节点。

last = prev;

3、节点于链表中间情况

clipboard.png

如果不仔细思考,我们在写程序时,会直接在两个if判断后,将剩余的相关操作写在一起。而源码并没有这么做,稍作分析,就能看出,如果前一个if中,条件是prev,因此可对该节点的prev进行相关操作。而后续的if语句,还需判断该节点的next引用,因此在第一个if-else语句体中,不对next进行操作,否则更改后,后学的next已经不是该节点的原next值。

因此,第一个if-else中:

prev.next = next;
x.prev = null;

第二个if-else中:

next.prev = prev;
x.next = null;

三、总结

从LinkedList的源码可以看到,源程序中相应方法代码简洁,逻辑清晰正确,在学习java的过程中,除了学习知识为我所用,也要避免闭门造车,多查看源码和其他优秀的项目程序,参考优秀的编程习惯和思想,从而积累经验,提高自己的水平。

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

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

相关文章

分块入门

我貌似和所有的数据结构都有些误会。。。。。。 在处理一些修改查询问题的时候&#xff0c;我们可以利用分治的思想&#xff0c;比如说把一个线性的数据不断分成一棵二叉树&#xff0c;也就是我们所说的线段树&#xff0c;这样我们就可以在logn的时限里做到修改和查询。同理我们…

开始使用gitlab

不得不说&#xff0c;我真不是一个合格的程序猿&#xff0c;工作马上两年了&#xff0c;github和gitlab用的一点也不熟练&#xff0c;每次兴致来了就搞几下&#xff0c;可是每次都浅尝辄止&#xff0c;不求甚解&#xff0c;时间一长&#xff0c;上一次练习的步骤就都记不起来了…

Spark 2.2.0 文档中文版 Collaborative Filtering 协同过滤 JAVA推荐系统

协同过滤常用于推荐系统&#xff0c;这项技术旨在填补 丢失的user-item关联矩阵 的条目&#xff0c;spark.ml目前支持基于模型的协同过滤&#xff08;用一些丢失条目的潜在因素在描述用户和产品&#xff09;。spark.ml使用ALS&#xff08;交替最小二乘法&#xff09;去学习这些…

淘宝top平台调用接口响应时间优化

我的专栏地址&#xff1a;我的segmentfault,欢迎浏览 一、背景 调用top接口的响应时间长&#xff08;160ms左右&#xff09;&#xff0c;超时和连接异常频繁发生。导致消息组件消费工程的tps遇到瓶颈&#xff08;单实例单消息队列250tps&#xff09;&#xff0c;只能通过增加实…

树上倍增一些理解和写法

树上倍增可以比较容易求得i节点的第k个父亲&#xff0c;我们定义一个二维数组fa[i][j]代表节点i的第2^j个父亲&#xff0c;关于有什么用我们等会再说&#xff0c;现在先学会怎么去求这个fa数组 我们可以通过从根节点开始一遍dfs求得所有fa数组&#xff0c;首先我们发现fa数组有…

图像去畸变和添加畸变

背景&#xff1a;最近的项目中用到的图像去畸变的知识&#xff0c;刚开始是直接调用opencv中提供的函数cv::initUndistortRectifyMap()和cv::remap()函数&#xff0c;实现图像的全局去畸变&#xff0c;但是由于图像的分辨率很高&#xff0c;再加上&#xff0c;实际过程中我们只…

win10上编译libharu库

背景&#xff1a; 最近的项目需要自动的生成pdf文件&#xff0c;我在网上查看相关的资料&#xff0c;发现目前比较流行的生成pdf文件的库有两个&#xff0c;一个是libpdf&#xff0c;另一个是libharu。libpdf个人使用时免费的但是商业使用就需要收费了&#xff0c;否则得到的p…

爬虫——正则表达式re模块

为什么要学习正则表达式 实际上爬虫一共就四个主要步骤&#xff1a; 明确目标&#xff1a;需清楚目标网站爬&#xff1a;将所有的目标网站的内容全部爬下来取&#xff1a;在爬下来的网站内容中去掉对我们没有用处的数据&#xff0c;只留取我们需要的数据处理数据&#xff1a;按…

深入Spring Boot:快速集成Dubbo + Hystrix

2019独角兽企业重金招聘Python工程师标准>>> 背景 Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点&#xff0c;从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离&#xff0c;请求缓存和请求打包&#xff…

BZOJ2333 [SCOI2011]棘手的操作 【离线 + 线段树】

题目 有N个节点&#xff0c;标号从1到N&#xff0c;这N个节点一开始相互不连通。第i个节点的初始权值为a[i]&#xff0c;接下来有如下一些操作&#xff1a; U x y: 加一条边&#xff0c;连接第x个节点和第y个节点 A1 x v: 将第x个节点的权值增加v A2 x v: 将第x个节点所在的连通…

opencv图像仿射变换和普通旋转

背景&#xff1a;今天需要对程序生成的图像进行旋转90度和下采样操作&#xff0c;当然还有改变图像类型的操作&#xff0c;就是把原来.png的图像转换为.jpg的图像&#xff0c;主要是我目前使用libharu库&#xff0c;无法成功从本地加载png图像到pdf中去&#xff0c;不得不使用j…

讨厌麻烦的ora 01722无效数字

webservice开发过程中&#xff0c;数据库由原来的oracle改为现在的sql server。然后重新调试&#xff0c;结果报出ora 01722无效数字的错误。 由于连接oracle数据库的时候并没有问题&#xff0c;所以一开始我以为是数据库不同&#xff0c;导致部分数据类型差异&#xff0c;&…

CSS样式:覆盖规则

规则一&#xff1a;由于继承而发生样式冲突时&#xff0c;最近祖先获胜。 CSS的继承机制使得元素可以从包含它的祖先元素中继承样式&#xff0c;考虑下面这种情况: <html><head><title>rule 1</title><style>body {color:black;}p {color:blue;}…

try{}里有一个 return 语句,那么紧跟在这个 try 后的 finally {}里的 code 会 不会被执行,什么时候被执行,在 return 前还是后?...

这是一道面试题&#xff0c;首先finally{}里面的code肯定是会执行的&#xff0c;至于在return前还是后&#xff0c; 看答案说的是在return后执行&#xff0c;我觉得不对&#xff0c;百度了一下&#xff0c;有说return前的&#xff0c;有说return后的&#xff0c;还有return中间…

相机和镜头选型需要注意哪些问题

背景&#xff1a; 最近需要优于项目需求需要对工业相机和镜头进行选型&#xff0c;于是我就开启的学习相机之旅&#xff0c;虽然我一直在做机器视觉方向&#xff0c;但是我对相机的了解还是很少&#xff0c;我想正好趁这次机会好好学习一下。如果有错误的观点请指正。 一、相…

响应式网页布局 - W3Schools How-Tos 01

W3Schools教学系列 W3Schools是知名的网页设计&#xff0f;前端开发教学网站&#xff0c;不仅提供HTML、CSS、JavaScript等的详尽教学&#xff0c;还可以把它当作说明文件&#xff08;Documents&#xff09;。有经验的前端或多或少已经接触过这个网站&#xff0c;因为它经常出现…

正則表達式,终极使用!3个工具,搞定一切

文章前提&#xff0c;本人。不会正则的不论什么语法&#xff0c;仅仅懂一点正则的概念。本人从未自己写过正则&#xff0c;都是网上收罗进行改动的。相同。没有时间去研究正则。 可是为了方便&#xff0c;入手了几个工具。 如今就为大家一一展示。 第一个&#xff0c;regexBuil…

iOS 在tableview的侧滑事件里执行tableView.selectRow无效的解决办法

很奇怪的问题&#xff0c;在执行默认选中一个cell的时候&#xff0c;突然发现这句话不起作用了 &#xff08;我的场景是&#xff1a;当前cell侧滑删除后&#xff0c;默认选中上一个cell&#xff09; 搞了半天&#xff0c;终于发现罪魁祸首竟然是因为&#xff1a;这句话写在了侧…

VS2017 C++工程 执行python脚本

我解决了哪怕很小的一个问题&#xff0c;我也想记录下来来见证我的经历。 背景&#xff1a; 一、使用libhuru库生成pdf报告 最近参与一些测试工作&#xff0c;希望测试结束后能够根据测试得到的数据和图像自动生成测试报告&#xff0c;最开始调研到了生成报告的库有libharu和…

标准正弦波变频电源调制方式的实现

目前变频电源正不断向规模化、专业化、智能化、精细化方向发展。变频电源的技术随着工业电器电子制造的兴起而不断得到重视和发展。其中,中港扬以正弦脉SPWM为核心变频电源系统电路便是一个很好的代表。纯硬件电路在焊接电路上比较复杂&#xff0c;但是调节出来的SPWM波形比较完…