一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情。
LinkedList 源码分析-删除
节点删除的方式和节点追加类似,可以从头部删除,或从尾部删除。
从头部删除
源码:
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
final E element = f.item取出节点的值,当做方法的返回值final Node<E> next = f.next;取出节点的下一个节点f.item = null;和f.next = null;元素置空,帮助 GC 回收节点first = next;头节点的下一个节点成为头节点if (next == null)如果 next 为空,表明链表为空next.prev = null;链表不为空,头节点的前一个节点指向 nullsize--;和modCount++;修改链表大小和版本
从尾部删除
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}
final E element = l.item;取出尾节点的值,当做方法的返回值final Node<E> prev = l.prev;取出尾节点的上一个节点l.item = null;l.prev = null帮助 GC 回收头节点last = prev;尾节点的上一个节点成为尾节点if (prev == null)如果 prev 为空,表明链表为空prev.next = null;链表不为空,尾节点的前一个节点指向 nullsize--; modCount++;修改链表大小和版本
进行删除操作的时候,删除的节点,都会把其前后指向节点都置为 null,帮助 GC 进行回收。
链表结构的节点新增、删除都只是把前后节点的指向修改下就好了,所以 LinkedList 适宜在新增和删除频繁的场景下使用,相应的也就不适宜在查询场景频繁的情况下使用,但是查找效率低而ArrayList的遍历效率会比LinkedList的遍历效率高一些。LinkedList还实现了栈和队列的操作方法,因此也可以作为栈、队列和双端队列来使用。