LinkedList源码分析
作者:互联网
LinkedList源码分析
LinkedList底层数据结构是双向链表,它同时实现了List和Deque两个接口,插入和删除元素的时间复杂度均为O(1), 相比于ArrayList它在插入和删除元素操作上具有明显优势,同样它也是非线程安全的容器。由于实现了deque接口,因此linkedList也可以用于实现队列
成员变量
transient int size = 0; //容器中元素数量
transient Node<E> first; //指向第一个元素的指针
transient Node<E> last;//指向最后一个元素的指针
Node类
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;
}
}
添加元素
//在链表头部插入元素
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
// newNode成为第一个节点
f.prev = newNode;
size++;
modCount++;
}
//获取指定位置的元素
Node<E> node(int index) {
// assert isElementIndex(index);
//比较index位置与链表中间节点,确定左边区间还是右区间,减少遍历
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
//在右区间查找
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
//确定元素在链表中的位置
public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
//从首节点开始逐一遍历
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
//在链表表尾添加元素
public boolean add(E e) {
linkLast(e);
return true;
}
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++;
}
//在节点前添加元素
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++;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
//当前只有一个元素
if (next == null)
//相当于在表尾添加元素
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
删除节点
public boolean remove(Object o) {
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
//从第一个节点开始遍历
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
//修改指针指向
unlink(x);
return true;
}
}
}
return false;
}
E unlink(Node<E> x) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
标签:分析,Node,prev,LinkedList,++,next,源码,newNode,null 来源: https://www.cnblogs.com/crstly/p/15733697.html