一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第11天,点击查看活动详情。
LinkedList 源码分析-新增
新增节点时,我们可以选择从链表头部新增,或者是从链表尾部新增;add 方法默认是从尾部新增,addFirst 方法是从头部新增。
新增数据(尾部新增)
从尾部追加(add)
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
-
final Node<E> l = last;把尾节点数据暂存到局部变量 -
final Node<E> newNode = new Node<>(l, e, null);新建新的节点(l 是新节点的前一个节点,当前值是尾节点值,e 表示当前新增节点,当前新增节点后一个节点是 null) -
last = newNode;新建节点追加到尾部 -
if (l == null)如果链表为空(l 是尾节点,尾节点为空,链表即空),头部和尾部是同一个节点,都是新建的节点 -
size++;modCount++;大小和版本更改
新增数据(头部新增)
从头部追加(linkFirst)
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++;
}
final Node<E> f = first;头节点赋值给临时变量final Node<E> newNode = new Node<>(null, e, f);新建节点,前一个节点指向null,e 是新建节点,f 是新建节点的下一个节点,目前值是头节点的值first = newNode;新建节点成为头节点if (f == null)头节点为空,就是链表为空,头尾节点是一个节点 头部追加节点和尾部追加节点非常类似,只是前者是移动头节点的 prev 指向,后者是移动尾节点的 next 指向。size++;modCount++;大小和版本更改
指定元素前新增
从指定元素前新增(linkBefore)
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.next = newNode;
size++;
modCount++;
}
E e, Node<E> succ表示即将插入的元素以及指定位置的元素final Node<E> pred = succ.prev;将指定元素的上一个元素保存new Node<>(pred, e, succ);创建即将插入的元素对象succ.prev = newNode;更新succ的指向新插入的Node对象- 更新新插入Node对象的上一个Node对象的指向
size++; modCount++;大小和版本更改