LinkedList底层代码解析笔记
LinkedList是属于Sequence List,故遍历是用迭代器更快;
LinkedList继承自AbstractSequenceList、实现了List及Deque接口。其实AbstractSequenceList已经实现了List接口,这里标注出List只是更加清晰而已。AbstractSequenceList提供了List接口骨干性的实现以减少实现List接口的复杂度。Deque接口定义了双端队列的操作。
附上一张构造图(蓝色线条是继承,绿色线条是接口实现)如下:
其数据结构如下:
更清晰些:
说明:如上图所示,LinkedList底层使用的双向链表结构,有一个头结点和一个尾结点,双向链表意味着我们可以从头开始正向遍历,或者是从尾开始逆向遍历,并且可以针对头部和尾部进行相应的操作。
类的内部类:
说明:内部类Node就是实际的结点,用于存放实际元素的地方。
类的属性:
说明:LinkedList的属性非常简单,一个头结点、一个尾结点、一个表示链表中实际元素个数的变量。注意,头结点、尾结点都有transient关键字修饰,这也意味着在序列化时该域是不会序列化的。
LinkedList(Collection<? extends E>)型构造函数:
this();调用无参构造方法; addAll(c);添加集合中的所有的元素:
说明:会调用无参构造函数,并且会把集合中所有的元素添加到LinkedList中。
核心函数分析:
说明:add函数用于向LinkedList中添加一个元素,并且添加到链表尾部。具体添加到尾部的逻辑是由linkLast函数完成的;
如下:
说明:对于添加一个元素至链表中会调用add方法 -> linkLast方法。
说明:参数中的index表示在索引下标为index的结点(实际上是第index + 1个结点)的前面插入。在addAll函数中,addAll函数中还会调用到node函数,get函数也会调用到node函数,此函数是根据索引下标找到该结点并返回,具体代码如下
说明:在根据索引查找结点时,会有一个小优化,结点在前半段则从头开始遍历,在后半段则从尾开始遍历,这样就保证了只需要遍历最多一半结点就可以找到指定索引的结点。
如上在调用remove移除结点时,会调用到unlink函数,unlink函数具体如下:
说明:将指定的结点从链表中断开,不再累赘。设为null后,GC机制会处理掉;
清空所有的方法:
需要将每个元素的item,next,prev都设为空;
前面linkLast()方法已经分析过了,其实同理;当理解双向链表结构,其实就很简单了;
总结:
有些说法认为LinkedList做插入和删除更快,这种说法其实是不准确的:
(1)LinkedList做插入、删除的时候,慢在寻址,快在只需要改变前后Entry的引用地址
(2)ArrayList做插入、删除的时候,慢在数组元素的批量copy,快在寻址
所以,如果待插入、删除的元素是在数据结构的前半段尤其是非常靠前的位置的时候,LinkedList的效率将大大快过ArrayList,因为ArrayList将批量copy大量的元素;越往后,对于LinkedList来说,因为它是双向链表,所以在第2个元素后面插入一个数据和在倒数第2个元素后面插入一个元素在效率上基本没有差别,但是ArrayList由于要批量copy的元素越来越少,操作速度必然追上乃至超过LinkedList。
从这个分析看出,如果你十分确定你插入、删除的元素是在前半段,那么就使用LinkedList;如果你十分确定你删除、删除的元素在比较靠后的位置,那么可以考虑使用ArrayList。如果你不能确定你要做的插入、删除是在哪儿呢?那还是建议你使用LinkedList吧,因为一来LinkedList整体插入、删除的执行效率比较稳定,没有ArrayList这种越往后越快的情况;二来插入元素的时候,弄得不好ArrayList就要进行一次扩容,记住,ArrayList底层数组扩容是一个既消耗时间又消耗空间的操作。
LinkedList底层代码解析笔记的更多相关文章
- ArrayList底层代码解析笔记
通过底层代码可以学习到很多东西: public class ArrayList<E> extends AbstractList<E> implements List<E& ...
- 笔记-爬虫-js代码解析
笔记-爬虫-js代码解析 1. js代码解析 1.1. 前言 在爬取网站时经常会有js生成关键信息,而且js代码是混淆过的. 以瓜子二手车为例,直接请求https://www.guaz ...
- java笔记 -- java简单结构代码解析及注释
结构代码解析 public class FirstSample { public static void main(String[] args) { System.out.println(2.0-1. ...
- ArrayList和LinkedList的底层代码实现思想
ArrayList是Java众多集合类中的一个,实现List接口,List的父接口是Collection.ArrayList底层的数据结构是线性表中的顺序表,底层是一个长度可以动态增长的数组.数组有很 ...
- 【论文笔记】AutoML for MCA on Mobile Devices——论文解读与代码解析
理论部分 方法介绍 本节将详细介绍AMC的算法流程.AMC旨在自动地找出每层的冗余参数. AMC训练一个强化学习的策略,对每个卷积层会给出其action(即压缩率),然后根据压缩率进行裁枝.裁枝后,A ...
- Java集合---LinkedList源码解析
一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...
- LinkedList源码解析
LinkedList是基于链表结构的一种List,在分析LinkedList源码前有必要对链表结构进行说明.1.链表的概念链表是由一系列非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和 ...
- [Java] LinkedList / Queue - 源代码学习笔记
简单地画了下 LinkedList 的继承关系,如下图.只是画了关注的部分,并不是完整的关系图.本博文涉及的是 Queue, Deque, LinkedList 的源代码阅读笔记.关于 List 接口 ...
- ava集合---LinkedList源码解析
一.源码解析 public class LinkedList<E> extends AbstractSequentialList<E> implements List<E ...
随机推荐
- ThinkPHP3.2.3 目录介绍
ThinkPHP3.2.3 目录介绍,在开发中主要操作的目录就是在入口文件www/index.php中定义的www/application/文件目录了. www WEB部署目录 ├─index.ph ...
- ogeek babyrop
拖入ida 先用strncmp使一个随机数与输入比对,这里可以用\x00跳过strncmp 然后read()中的a1是我们输入\x00后的值 写exp from pwn import * sh=rem ...
- centos7.3安装wordpress
一.安装并配置数据库 1.安装mariadb #yum install -y mariadb-server mariadb 2.启动数据库并设置开机自启#systemctl start mariadb ...
- db2重组所有表和更新表统计信息
1.构建db2admin模式下的所有表的重组语句: select ' reorg table '||TABLE_NAME||';' from sysibm.tables where TABLE_SC ...
- 如何减少代码中的if-else嵌套
实际项目中,往往有大量的if-else语句进行各种逻辑校验,参数校验等等,大量的if-else,语句使代码变得臃肿且不好维护,本篇文章结合我自己的经验,就减少if-else语句给出以下几种方案,分别适 ...
- Pxe自动化安装
Centos7环境 Systemctl stop firewalld Setenforce Yum本地源 cd /etc/yum.repos.d/ 进入/etc/yum.repos.d/ Ls 查看 ...
- 低门槛彻底理解JavaScript中的深拷贝和浅拷贝
作者 | 吴胜斌 来源 | https://www.simbawu.com/article/search/9 在说深拷贝与浅拷贝前,我们先看两个简单的案例: //案例1var num1 = 1, nu ...
- java命令-jstat/ javap
jstat命令对应用程序资源和性能进行实时监控 常用参数列举如下: 1. jstat -class pid 显示加载class的数量.所占空间.所耗时间等信息 2.jstat -compiler pi ...
- case when使用的总结
https://blog.csdn.net/changxiangyangy/article/details/86718551 前几天,为了给产品分析当前用户数据结构,写sql的时候使用到了case w ...
- 小程序内嵌H5页面判断微信及小程序环境
判断微信及小程序环境 1.H5页面引入jweixin-1.3.2.js 2. var ua = window.navigator.userAgent.toLowerCase(); if(ua.matc ...