Deque接口
支持两端元素插入和移除的线性集合。
public interface Deque<E> extends Queue<E> {
//插入此双端队列的前面
void addFirst(E e);
//插入此双端队列的末尾
void addLast(E e);
//在此deque的前面插入指定的元素
boolean offerFirst(E e);
boolean offerLast(E e);
//检索并删除此deque的第一个元素。
E removeFirst();
//检索并删除此deque的第一个元素,如果此deque为空,则返回 null 。
E pollFirst();
//检索,但不删除,这个deque的第一个元素。
E getFirst();
//检索但不删除由此deque表示的队列的头部(换句话说,此deque的第一个元素),如果此deque为空,则返回 null 。
E peekFirst();
//从此deque中删除指定元素的第一个出现。
boolean removeFirstOccurrence(Object o);
//将元素推送到由此deque表示的堆栈first
void push(E e);
//从这个deque表示的堆栈中弹出一个元素。 first
E pop();
}
AbstractSequentialList抽象类
对AbstractList中的方法进行了进一步构造,主要是对ListIterator迭代
public abstract class AbstractSequentialList<E> extends AbstractList<E> {
add()
remove()
get()
set()
}
LinkedList类
特点
- 随机访问效率低,因为每查找一个节点都要遍历一次
- 双向链表,可作为队列和栈
- 线程不安全
- 元素可为null
- 增删快,查找慢
链表中节点的定义
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 class ListItr implements ListIterator<E> {
//next的返回节点
private Node<E> lastReturned;
//下一节点
private Node<E> next;
//下一节点索引
private int nextIndex;
//结构修改次数
private int expectedModCount = modCount;
//返回指定位置的节点
ListItr(int index) {
next = (index == size) ? null : node(index);
nextIndex = index;
}
public E next() {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public void remove() {
checkForComodification();
if (lastReturned == null)
throw new IllegalStateException();
//删除节点的下一节点
Node<E> lastNext = lastReturned.next;
//将节点从链表中删除,modCount++
unlink(lastReturned);
//如果next=删除节点则next后移
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null;
expectedModCount++;
}
}
成员变量
//链表大小
transient int size = 0;
//链表第一个节点
transient Node<E> first;
//链表最后一个节点
transient Node<E> last;
主要方法
- 将节点从当前链表除去
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;
}
//节点值置null,返回删除的元素
x.item = null;
size--;
modCount++;
return element;
}
- 搜索返回指定位置的节点
Node<E> node(int index) {
//如果输入位置在前半部分则从前开始遍历next
//如果输入位置在后半部分则从后开始遍历prev
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 boolean add(E e) {
linkLast(e);//在链表末尾插入元素
return true;
}
public void add(int index, E element) {
checkPositionIndex(index);
//插入末尾
if (index == size)
linkLast(element);
//找到index位置的节点,然后在节点前插入
else
linkBefore(element, node(index));
}
//在链表最后插入
void linkLast(E e) {
final Node<E> l = last;
//new新节点,初始prev为last
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
//prev节点的next链接新节点
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
//在某个节点前插入
void linkBefore(E e, Node<E> succ) {
final Node<E> pred = succ.prev;
//new新节点,初始prev为succ的prev,next为succ
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
//prev节点的next链接新节点
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
offerFirst->addFirst->linkFirst将元素添加都链表首位
- 删除
//默认删除first
public E remove() {
return removeFirst();
}
//遍历删除指定元素
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;
}