一、源码分析
双向链表
1. LinkedList 类组成
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable //1. 实现接口List、Deque { transient int size = 0; /** * Pointer to first node. * Invariant: (first == null && last == null) || * (first.prev == null && first.item != null) */ transient Node<E> first; // 2. first 节点 /** * Pointer to last node. * Invariant: (first == null && last == null) || * (last.next == null && last.item != null) */ transient Node<E> last; // 3. last 节点 /** * Constructs an empty list. */ public LinkedList() { // 4. 构造函数 }
2. Node<E> 节点接口
private static class Node<E> { E item; // 1. data Node<E> next; // 2. next potioner Node<E> prev; // 3. prev potioner Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
3. add(e) 新增
public boolean add(E e) { linkLast(e); return true; } /** * Links e as last element. */ void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); // add 数据Node last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; }
4. get(index) 查找
public E get(int index) { checkElementIndex(index); return node(index).item; } private void checkElementIndex(int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } /** * Tells if the argument is the index of an existing element. */ private boolean isElementIndex(int index) { return index >= 0 && index < size; }
/**
* Returns the (non-null) Node at the specified element index.
*/
Node<E> node(int index) { // !!!折半遍历查找
// assert isElementIndex(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;
}
}
5. remove(index) 删除
public E remove(int index) { checkElementIndex(index); return unlink(node(index)); } /** * Unlinks non-null node x. */ E unlink(Node<E> x) { // assert x != null; final E element = x.item; // 1. 移动next prev 纸箱即可 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; }
n. 问题分析
1. LinkedList 优势?
LinkedList 基于双向链表实现, 因此具有链表 插入快、 索引慢的特性;
2. Deque extends Queue. 双端队列。