啃透JDK源码-LinkedList
0 前言
与 ArrayList 一样实现了 List 接口,只是 LinkedList 底层结构为链表.在插入和删除时更优于 ArrayList,而随机访问则比 ArrayList 稍逊.
其允许元素包括 null.除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。
该类还实现了 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。
所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端).
1 继承体系
LinkedList 继承自 AbstractSequentialList,又实现了 List、Deque、Cloneable、Serializable等接口.
AbstractSequentialList相较于AbstractList(ArrayList的父类),只支持次序访问,而不支持随机访问,因为它的get(int index) ,set(int index, E element), add(int index, E element), remove(int index) 都是基于迭代器实现的。
Deque - 线性 collection,支持在两端插入和移除元素,定义了双端队列的操作.
2 属性
双向链表定义方式.
-
头节点的指针.不变性约束条件:(first == null && last == null) || (first.prev == null && first.item != null)
-
尾节点的指针.不变性约束条件:(first == null && last == null) || (last.next == null && last.item != null)
-
表示 LinkedList 的大小
-
节点Node
可以看出,这是一个典型的双向链表的结构
3 构造方法
3.1 无参
- 构造一个空list
3.2 有参
- 构造一个包含指定 collection 中的元素的list,这些元素按其 collection 的迭代器返回的顺序排列。
下面开始看各大核心 API 细节.
4 add
4.1 末尾添加
add(E e)
- 将指定元素添加到此 list 的末尾
linkLast(E e)
add(E e)等价于addLast(E e),因为 LinkedList 实现了 Deque 接口.
addLast(E e)
核心都是linkLast方法.
- 图解末尾添加
4.2 首位添加
addFirst(E e)
linkFirst(E e)
- 图解首位添加
主要流程:
- 将原 first 节点保存到 f
- 将插入元素封装成 newNode,并且该新节点的next指向原来的头节点,即f
- 若原来的头节点 f 为null,那么新插入头节点也是 last 尾节点,否则设置 f 的前置节点为NewNode,即 NewNode 现在是first 头节点.
- size加一,修改计数器加一
4.3 指定位置插入
add(int index, E element)
首先调用checkPositionIndex检查index值是否在范围内
checkPositionIndex
isPositionIndex
- 判断参数是否为迭代器或者添加操作的有效位置的索引.
如果index在最后的话,就调用在尾部插入的函数,否则调用LinkBefore
LinkBefore
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
- 图解指定位置插入元素
5 remove
- 因为 Deque 接口,所以本类也实现了如下方法支持双端操作:
5.1 removeFirst()
unlinkFirst(Node f)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
5.2 removeLast
unlinkLast
删除非空的尾节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
remove(int index)
在指定index删除
检验index是否合法.如果删除成功,返回删除的节点。 具体实现在unlink
unlink
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
- 图解 unlink 过程
- 流程如下:
- 将删除的节点保存在element,同时把要删除节点的前驱节点标记为prev,后继节点标记为next
- 若prev为null,则 next 节点直接为 first 节点,反之把prev的next指向next节点,如图上面弯曲的红色箭头
- 若 next 为空,那么prev节点直接为last节点,反之把next的prev指向prev节点,如图下面弯曲的蓝色箭头
- 把要删除的节点置空,返回第一步保存的element
remove(Object o)
- o 为 null,遍历链表,找到第一个为 null 的节点删除
- o 非 null,遍历链表,找到第一个值相等的节点,调用unlink(x)删除
6 get
迭代,比对,然后返回值而已.
get(int index)
getFirst()
返回此列表的第一个元素
getLast()
返回此列表的最后一个元素。
indexOf(Object o)
返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1
https://stackoverflow.com/questions/23539087/consistency-check-for-a-linked-list
文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。
原文链接:javaedge.blog.csdn.net/article/details/105315623
- 点赞
- 收藏
- 关注作者
评论(0)