1. 概述
- 底层使用双向链表实现;
- 支持对头节点和尾节点进行直接操作;
- 元素可以为null;
- 元素的增加删除效率较高,增加删除时只需要改变当前节点和前后节点的关系即可.
- 元素的查询操作效率较低,需要一个一个遍历查找.
- 此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。
2. 基本属性
// 元素总数
transient int size = 0;
// 头节点
transient Node<E> first;
// 尾节点
transient Node<E> last;
3. 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;
}
}
4. 迭代器
private class ListItr implements ListIterator<E> {
// 当前节点
private Node<E> lastReturned;
// 下一个节点
private Node<E> next;
// 当前遍历的节点 位置
private int nextIndex;
// 链表结构的修改次数
private int expectedModCount = modCount;
ListItr(int index) {
// 初始化时 index=0
next = (index == size) ? null : node(index);
nextIndex = index;
}
public boolean hasNext() {
return nextIndex < size;
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious() {
return nextIndex > 0;
}
public E previous() {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex() {
return nextIndex;
}
public int previousIndex() {
return nextIndex - 1;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
public void set(E e) {
if (lastReturned == null)
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add(E e) {
checkForComodification();
lastReturned = null;
if (next == null)
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size) {
action.accept(next.item);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
// 快速失败
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}