jdk源码--LinkedList
本文基于jdk1.8_171
LinkedList介绍
之前看了ArrayList,内部是一个数组。这次看了LinkedList,作用和ArrayList一样,但是内部是链表形式。链表结构如下图:
数组和链表的区别
直接看例子:
数组: 假设有10个人去看电影,想要挨着坐,那就需要找同一排连续的10个位置坐(座位号01-10)。如果想要找5号先生,那直接去第五个座位即可。但是,如果此时来了第十一个人,想要坐在4号和5号先生的位置中间,那么原本5号先生和后面的所有人都要往后挪个位置,然后11号先生才能落座。
链表: 还是10个人去看电影,不用挨着坐,每个人记着自己前一个人和后一个人坐哪里就行,第一个人记下一个人和最后一个人记上一个人。此时还是来了第十一个人,想要坐在4号和5号先生的位置中间(不是空间意义的中间),那么5号先生更换自己上家为11号,4号先生更换下家为11号,11号记自己上家是4号,下家是5号即可。但是如果需要找到5号的位置,那你需要先找1号,问他下家2号在哪里,然后找2号下家3号。。。一直找到5号。
所以结论:数组查找元素比链表快,但往中间插入元素链表比数组快。
内部类
/**
* 链表内部元素
*/
class Node<E>{
	//当前元素
	E item;
	//上一个元素
	Node<E> prev;
	//下一个元素
	Node<E> next;
	Node(Node<E> prev,E element,Node<E> next){
		this.item = element;
		this.next = next;
		this.prev = prev;
	}
}
成员变量
//元素个数
transient int size = 0;
//链表第一个元素
transient Node<E> first;
//链表最后一个元素
transient Node<E> last;
常用方法
1、addFirst(E e)
public void addFirst(E e){
	linkFirst(e);
}
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();
	else
		//如果链表原先不为空,那么原先第一个元素的前一位指向新元素
		f.prev = newNode;
	//链表元素个数加一
	size++;
	//集合修改次数加一
	modCount++;
}
addLast类似,不赘述。
2、add(E e)
public boolean add(E e){
	//add方法就是在链表末尾添加元素
	linkLast(e);
	return true;
}
3、add(int index,E element)
public void add(int index,E element){
	//这一步就是检查index是否越界,越界就抛出异常
	checkElementIndex(index);
	//如果index是size,就加在链表最后,否则就加在指定元素之前
	if(index == size)
		linkLast(element);
	else
		//node(index)方法解析往下看
		linkBefore(element,node(index));
}
void linkBefore(E e,Node<E> succ){
	//assert succ !=null
	//缓存指定元素的前一个元素
	final Node<E> pred = succ.prev;
	//要插入的新元素
	final Node<E> newNode = new Node<>(pred, e, succ);
	//指定元素的前一位变成新元素
	succ.prev = newNode;
	if(pred == null){
		//如果指定元素是第一个,那么新元素就变成第一个元素
		first = newNode;
	} else {
		//缓存的pred的下一个元素变成新元素
		pred.next = newNode;
	}
	size++;
	modCount++;
}
4、get(int index)
public E get(int index){
	checkElementIndex(index);
	//node(index)方法解析往下看
	return node(index).item;
}
Node<E> node(int index){
	if(index < (size >> 1)){
		//如果index小于size的一半,则从头开始找
		//先找到第一个元素
		Node<E> x = first;
		//往后找index次,我看的时候第一次没理解,举了例才明白,比如index=1,size=4等等
		for(int i=0; i < index; i++)
			x = x.next;
		return x;
	} else {
		//从尾开始找
		//先找到最后一个元素
		Node<E> x = last;
		//往前找index次
		for(int i = size - 1; i > index; i--)
			x = x.prev;
		return x;
	}
}
结语
LinkedList有自身的优点,虽然实际运用不如ArrayList频繁,但我们依然要了解它的特性以及实现方式。
jdk源码--LinkedList的更多相关文章
- JDK源码分析(三)—— LinkedList
		参考文档 JDK源码分析(4)之 LinkedList 相关 
- JDK源码分析(2)LinkedList
		JDK版本 LinkedList简介 LinkedList 是一个继承于AbstractSequentialList的双向链表.它也可以被当作堆栈.队列或双端队列进行操作. LinkedList 实现 ... 
- JDK源码学习LinkedList
		LinkedList是List接口的子类,它底层数据结构是双向循环链表.LinkedList还实现了Deque接口(double-end-queue双端队列,线性collection,支持在两端插入和 ... 
- 一点一点看JDK源码(六)java.util.LinkedList前篇之链表概要
		一点一点看JDK源码(六)java.util.LinkedList前篇之链表概要 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.什么 ... 
- JDK源码学习系列05----LinkedList
		JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ... 
- 【java基础之jdk源码】集合类
		最近在整理JAVA 基础知识,从jdk源码入手,今天就jdk中 java.util包下集合类进行理解 先看图 从类图结构可以了解 java.util包下的2个大类: 1.Collecton:可以理解为 ... 
- Java中集合框架,Collection接口、Set接口、List接口、Map接口,已经常用的它们的实现类,简单的JDK源码分析底层实现
		(一)集合框架: Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(实现接口的类).所有抽象出来的数据结构和操作(算法)统称为集合框架. 程序员在具体应用的时候,不必考虑数据结构和 ... 
- JDK源码阅读顺序
		很多java开发的小伙伴都会阅读jdk源码,然而确不知道应该从哪读起.以下为小编整理的通常所需阅读的源码范围. 标题为包名,后面序号为优先级1-4,优先级递减 1.java.lang 1) Obj ... 
- 一点一点看JDK源码(〇)
		一点一点看JDK源码(〇) liuyuhang原创,未经允许进制转载 写在前面: 几乎所有的大神都会强调看源码,也强调源码的重要性: 但是如何看源码,源码看什么?看了什么用?看了怎么用? 困扰很多人, ... 
随机推荐
- 插入2D点,在WPF中使用Bezier曲线
			原文Interpolate 2D points, usign Bezier curves in WPF Interpolate 2D points, usign Bezier curves in WP ... 
- 树莓派3B 无显示器,无键盘,无Linux系统,无网线 配置WIFI连接
			#1.基本需求#2.烧写镜像#3.用有线网(网线)连接PC,实现远程操作树莓派#4.接入无线网,通过其它电脑远程控制树莓派#5.使用PC共享的热点Wifi远程控制树莓派 #1.基本需求 树莓派 USB ... 
- texbox 禁用copy paster cut
			<TextBox CommandManager.PreviewExecuted="textBox_PreviewExecuted" ContextMenu="{x: ... 
- wpf屏蔽快捷键alt+space,alt+F4
			/// <summary> /// 阻止 alt+f4和alt+space 按键 /// </summary> /// <par ... 
- Win8 Metro(C#)数字图像处理--2.56简单统计法图像二值化
			原文:Win8 Metro(C#)数字图像处理--2.56简单统计法图像二值化  [函数名称] 简单统计法图像二值化 WriteableBitmap StatisticalThSegment(Wr ... 
- 微信小程序把玩(四十一)canvas API
			原文:微信小程序把玩(四十一)canvas API 绘图是每个移动应用必备的技术,基本上和Android,IOS,等移动开发都是相同的,创建个上下文,给你个画布再上画,官网给的小例子都比较全了自己去看 ... 
- Windows下 Composer 安装 Thinkphp5 的记录.
			首先安装Composer, 下载地址: https://www.phpcomposer.com/ Windows安装过程及其简单,请自行搜索解决. 接下来Win+R, 启动命令行窗口,以下所有操作都是 ... 
- RIO的性能
			看了一下微软官网RIO没有达到四五倍的宣称(而且必须在windows 2012r2才可以)最多一倍github.com/aspnet/benchmarks测试代码可以从github.com/zelia ... 
- zynqmp(zcu102rev1.0)系列---1---安装 xsdk
			Xilinx 的zynq7020在设备上面已经使用上,并量产,关于zynq7020使用总结将在近期同步进行. 该系列主要记录Xilinx zynqmp系列 的使用以及在遇到的问题.目前手上有一块dem ... 
- SIP:用Riverbank的SIP创建C++库的Python模块(把自己的C++库包装成Python模块)
			我们发现PyQt做的Python版的PyQt是如此好用,如果想把自己的C++库包装成Python模块该如何实现呢? 这里介绍下用SIP包装C++库时值得参考的功能实现: 需要Python模块中实现C+ ... 
