LinkedList的继承关系
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.AbstractSequentialList<E>
↳ java.util.LinkedList<E>
public class LinkedList<E> extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}
第1部分 LinkedList介绍
a. LinkedList 是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。b. LinkedList 实现 List 接口,能对它进行队列操作。
c. LinkedList 实现 Deque 接口,即能将LinkedList当作双端队列使用。
d. LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
e. LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
LinkedList 是非同步的。
通过如下代码实现双向链表,所以不存在容量不足的问题
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;
}
}
第2部分 LinkedList详细介绍
每种方法都存在两种形式:一种形式在操作失败时抛出异常,另一种形式返回一个特殊值(null或false)
抛出异常 抛出异常
插入方法 addFirst(e); offerFirst(e); addLast(e); offerLast(e);
移除方法 removeFirst(); pollFirst(); removeLast(); pollLast();
检查方法 getFirst(); peekFirst(); getLast(); peekLast();
a.先进先出(堆模式)
队列方法 等效方法
add(e); addLast(e);
offer(e); offerLast(e); // 增加一个元素 调用linkLast方法
remove(); removeFirst();
poll(); pollFirst(); // 移除第一个元素,并且返回
element(); getFirst();
peek(); peekFirst(); // 返回链表中第一个元素
b.后进先出(栈模式)
栈方法 等效方法
push(e); addFirst(e); // 增加一个元素 调用linkFirst方法
pop(); removeFirst();
peek(); peekFirst();
第3部分 LinkedList源码解析
// 链表头增加一个元素
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
f.prev = newNode;
size++;
modCount++; // 增加 fast-fail机制
}
// 链表尾增加一个元素
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++;
}
// 删除链接头元素
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;
}
// 删除链表尾元素
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
final E element = l.item;
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;
}
第4部分 LinkedList遍历方式
(01)第一种,通过迭代器遍历,10000的数据量大概8ms
for(Iterator iter = list.iterator(); iter.hasNext();)
iter.next();
(02)通过快速随机访问遍历,10000的数据量大概3724ms,因为随机访问遍历通过ListIterator来遍历的所以最慢
int size = list.size();
for(int i = 0 ; i < size; i++);
list.get(i);
(03) 通过for循环遍历,10000的数据量大概5ms
for(Integer integ: list)
(04)通过pollFirst()来遍历,10000的数据量大概8ms
while(list.pollFirst()!=null)
(05)通过pollLast来遍历,10000的数据量大概6ms
while(list.pollLast()!=null
(06)通过removeFirst来遍历,10000的数据量大概2ms
(07)通过removeLast来遍历,10000的数据量大概2ms