Java集合-LinkedList源码分析
1.数据结构-链表
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。
链表的类型:
单向链表:单向链表包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。
双向链表:双向链表每个节点有两个连接:一个指向前一个节点,(当此“连接”为第一个“连接”时,指向空值或者空列表);而另一个指向下一个节点,(当此“连接”为最后一个“连接”时,指向空值或者空列表)
循环链表:在一个循环链表中, 首节点和末节点被连接在一起。
2.ArrayList结构特性
LinkedList 与 ArrayList 一样实现 List 接口,只是 ArrayList 是 List 接口的大小可变数组的实现,LinkedList 是 List 接口链表的实现。有以下特性:
- 允许包含重复的元素
- 允许包含null元素
- 保存了元素添加的顺序
- 不是线程安全的
3.构造方法
// 1.构造一个空列表
LinkedList()
// 2.构造一个包含指定集合元素的列表
LinkedList(Collection<? extends E> c)
4.成员变量
// 1.链表中的元素数
transient int size
// 2.指向第一个元素的指针
transient Node<E> first
// 3.指向最后一个元素的指针
transient Node<E> last
5.常用的成员方法
// 1.添加一个元素到列表的尾部
boolean add(E e)
// 2.添加一个元素到列表的指定位置
void add(int index, E element)
// 3.将指定集合中的所有元素追加到此列表的末尾。
boolean addAll(Collection<? extends E> c)
// 4.添加一个元素到列表的头部
void addFirst(E e)
// 5.添加一个元素到列表的尾部
addLast(E e)
// 6.检查列表中包含指定的元素
boolean contains(Object o)
// 7.返回列表的第一个元素
E element()
// 8.返回列表指定位置的元素
E get(int index)
// 9.返回指定元素在列表中首次出现的索引
int indexOf(Object o)
// 10.返回指定元素在列表中最后一次出现的索引
int lastIndexOf(Object o)
// 11.添加一个元素到列表的尾部
boolean offer(E e)
// 12.返回列表的第一个元素
E peek()
// 13.删除并返回此列表的第一个元素
E poll()
// 14.删除并返回此列表的第一个元素
E pop()
// 15.添加一个元素到列表的头部
void push(E e)
// 16.移除列表的第一个元素
E remove()
// 17.设置指定位置的元素
E set(int index, E element)
// 18.返回列表中的元素数
int size()
// 19.返回一个数组,包含列表中所有元素
Object[] toArray()
6.Node节点
// LinkedList的静态内部类
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;
}
}
7.序列化原理
1.LinkedList 实现了Serializable接口,支持对象序列化
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
......
}
2.序列化时调用 writeObject 方法,将 size 和 node 节点列表写入 ObjectOutputStream。
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
// Write out any hidden serialization magic
s.defaultWriteObject();
// 序列化 size
s.writeInt(size);
// 从第一个元素开始,将链表中所有的元素序列化
for (Node<E> x = first; x != null; x = x.next)
s.writeObject(x.item);
}
3.反序列化时调用 readObject 方法,恢复 size 和 node 节点列表。
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in any hidden serialization magic
s.defaultReadObject();
// 恢复size
int size = s.readInt();
// 恢复链表
for (int i = 0; i < size; i++)
linkLast((E)s.readObject());
}
4.成员变量 size、first 和 last 使用 transient 关键字修饰,不会序列化到目的地中,从而节省时间和空间。
8.迭代器
1.由LinedList内部类ListItr实现ListIterator 接口,间接实现Iterator 接口。
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
// 最近返回的节点引用
private Node<E> lastReturned;
// 下一个节点的引用
private Node<E> next;
// 下一个节点的位置索引
private int nextIndex;
private int expectedModCount = modCount;
......
}
2.ListItr实现迭代器的成员方法
// 检查指针索引指向链表的边界
public boolean hasNext() {
return nextIndex < size;
}
// 返回next 指向的节点,同时next偏移下一个节点
public E next() {
......
}
// 移除最近返回的节点(lastReturned引用)
public void remove() {
......
}
9.总结
以上就是对LinkedList的理解,如果有不正确的地方,欢迎指正,最后,补一张脑图:

Java集合-LinkedList源码分析的更多相关文章
- Java入门系列之集合LinkedList源码分析(九)
前言 上一节我们手写实现了单链表和双链表,本节我们来看看源码是如何实现的并且对比手动实现有哪些可优化的地方. LinkedList源码分析 通过上一节我们对双链表原理的讲解,同时我们对照如下图也可知道 ...
- Java集合---LinkedList源码解析
一.源码解析1. LinkedList类定义2.LinkedList数据结构原理3.私有属性4.构造方法5.元素添加add()及原理6.删除数据remove()7.数据获取get()8.数据复制clo ...
- Java集合——LinkedList源码详解
)LinkedList直接继承于AbstractSequentialList,同时实现了List接口,也实现了Deque接口. AbstractSequentialList为顺序访问的数据存储结构提供 ...
- Java集合框架源码分析(2)LinkedList
链表(LinkedList) 数组(array)和数组列表(ArrayList)都有一个重大的缺陷: 从数组的中间位置删除一个元素要付出很大的代价,因为数组中在被删除元素之后的所有元素都要向数组的前端 ...
- java.util.LinkedList源码分析
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, D ...
- java中LinkedList源码分析
ArrayList是动态数组,其实本质就是对数组的操作.那么LinkedList实现原理和ArrayList是完全不一样的.现在就来分析一下ArrayList和LinkeList的优劣吧LinkedL ...
- Java集合-ArrayList源码分析
目录 1.结构特性 2.构造函数 3.成员变量 4.常用的成员方法 5.底层数组扩容原理 6.序列化原理 7.集合元素排序 8.迭代器的实现 9.总结 1.结构特性 Java ArrayList类使用 ...
- java集合系列之LinkedList源码分析
java集合系列之LinkedList源码分析 LinkedList数据结构简介 LinkedList底层是通过双端双向链表实现的,其基本数据结构如下,每一个节点类为Node对象,每个Node节点包含 ...
- Java集合之LinkedList源码分析
概述 LinkedLIst和ArrayLIst一样, 都实现了List接口, 但其内部的数据结构不同, LinkedList是基于链表实现的(从名字也能看出来), 随机访问效率要比ArrayList差 ...
随机推荐
- 自动化集成:Pipeline流水语法详解
前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S相关组件,实现自动化管理源码编译.打包.镜像构建.部署等操作:本篇文章主要描述Pipeline流水线用法. 一.Webhook原理 ...
- CF469A I Wanna Be the Guy 题解
Content 小 A 和小 B 正在玩一个游戏,游戏一共有 \(n\) 关,而两个人各只能通过 \(p_A,p_B\) 个关卡.问他们能否通过合作通关这个游戏. 数据范围:\(1\leqslant ...
- LuoguB2034 计算 2 的幂 题解
Content 给定整数 \(n\),求 \(2^n\). 数据范围:\(0\leqslant n<31\). Solution 第一种各位都能想得到的,直接循环 \(n\) 次,往答案里面乘以 ...
- java 多线程: Thread 锁ReentrantLock 常用方法
注意 reentrantLock 和 同步代码块儿一样,同一个时刻只能一个线程获取锁,也就是共用锁的代码块部分,线程是顺序执行的 ReentrantLock 常用方法 getHoldCount获取当前 ...
- ubuntu16.04 开启ipv6支持
1)vim /etc/default/grub将GRUB_CMDLINE_LINUX中下面的这一项删除:ipv6.disable=12)执行 grub-mkconfig -o /boot/grub/ ...
- 【LeetCode】521. Longest Uncommon Subsequence I 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP
MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP,其中 DATE 类型用于表示日期,但是不会包含时间,格式为 YYYY-MM-DD,而 DATETIME 和 T ...
- 第二十八个知识点:什么是公钥密码学的IND-CCA安全定义?
第二十八个知识点:什么是公钥密码学的IND-CCA安全定义? 我们将在这篇博客中讨论公钥加密的IND-CCA安全. IND-CCA安全代表选择明文的不可伪造性.这样的安全方案的思想就是给定一个密文,攻 ...
- 「算法笔记」期望 DP 入门
一.数学期望 1. 由来 在 \(17\) 世纪,有一个赌徒向法国著名数学家帕斯卡挑战,给他出了一道题目:甲乙两个人赌博,他们两人获胜的机率相等,比赛规则是先胜三局者为赢家,一共进行五局,赢家可以获得 ...
- 比例阀驱动电路后级PWM滤波尖刺如何消除?PWM通过RC低通滤波器模拟DAC
双头比例阀驱动电路,采用单片机输出2路PWM,分别驱动功率器件(U100的2和4脚),经过U100的8和10脚输出供电电源的高压PWM波形,这个高压PWM经过R104和R114分别采样后经过电流放大器 ...