LinkedList源码分析
1、成员变量
transient int size = 0;
transient Node<E> first; // 头节点
transient Node<E> last; // 尾节点
2、add()方法
/**
* 将指定元素追加到list末尾
*/
public boolean add(E e) {
linkLast(e);
return true;
}
/**
* 在指定位置插入元素
*/
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element); // 插入到尾部
else
// 插入到指定位置,并将原位置的节点移动到下一个位置
linkBefore(element, node(index));
}
/**
* 将元素作为最后一个节点插入链表
*/
void linkLast(E e) {
final Node<E> l = last; // 当前尾节点
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null) // 没有尾节点(list为空),将头节点也设置为newNode
first = newNode;
else
l.next = newNode; // 当前尾节点的下一个节点设置为newNode
size++;
modCount++;
}
/**
* 在succ元素之前插入一个节点
*/
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev; // succ的前一个节点
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null) // 没有前一个节点,表示succ已经是头节点
first = newNode;
else
pred.next = newNode; // succ前节点的next赋值为newNode
size++;
modCount++;
}
检查索引是否合法:
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private boolean isPositionIndex(int index) {
// 检查索引是否合法
return index >= 0 && index <= size;
}
3、get()方法
public E get(int index) {
// 检查索引是否合法
checkElementIndex(index);
return node(index).item;
}
Node<E> node(int index) {
// assert isElementIndex(index);
if (index < (size >> 1)) {
// index小于size的一半,说明index在list前半部分,从头节点开始遍历
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
// index大于等于size的一半,说明index在list后半部分,从尾节点开始遍历
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
4、set()方法
public E set(int index, E element) {
// 检查索引是否合法
checkElementIndex(index);
Node<E> x = node(index); // 根据index找到目标节点
E oldVal = x.item;
x.item = element; // 将目标节点的item替换为element
return oldVal; // 返回原来的值
}
5、remove()方法
/**
* 移除第一个与指定元素相等的节点
*/
public boolean remove(Object o) {
if (o == null) { // 如果指定的节点值是null,移除list中第一个null节点
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else { // 使用equals方法找到指定节点
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
/**
* 根据位置移除节点
*/
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
/**
* 移除一个非空的节点 x
*/
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) { // x为头结点
first = next;
} else {
prev.next = next; // x的前后节点直接相连
x.prev = null; // 断开X与前节点的连接
}
if (next == null) { // x为尾结点
last = prev;
} else {
next.prev = prev; // x的前后节点直接相连
x.next = null; // 断开X与后节点的连接
}
x.item = null; // 清空x的数据存储
size--;
modCount++;
return element;
}
未完,待续...