JDK 1.8 源码解析 LinkedList

时间:2021-04-18 17:17:58

   LinkedList原理:

  JDK 1.8 源码解析 LinkedList

  1 基于循环双链表,持有首尾结点引用和存储了元素数量,适合元素的添加和删除。链表结点类包含存储的元素、前驱结点引用和后继结点引用。

  2 size方法用于获取元素数量,isEmpty方法用于判断是否为空。

  3 实现了List接口,add方法用于尾部插入指定元素,remove方法用于删除指定元素。

  4 实现了Queue接口(Deque接口继承了Queue接口),add方法用于队尾插入指定元素,remove方法用于队头获取并删除元素。

  JDK 1.8 源码解析 LinkedList

  5 实现了Deque接口,addFirst方法用于队头插入指定元素,removeFirst方法用于队头获取并删除元素,addLast方法用于队尾插入指定元素,removeLast方法用于队尾获取并删除元素。

  JDK 1.8 源码解析 LinkedList

  JDK 1.8 源码解析 LinkedList

  JDK 1.8 源码解析 LinkedList

  

package java.util;

 

// 继承了AbstractSequentialList // 实现了List、Deque、Cloneable和java.io.Serializable接口
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

 

// 元素数量
transient int size = 0;

 

// 首结点引用
transient Node<E> first;

 

// 尾结点引用
transient Node<E> last;

 

// 无参构造方法
public LinkedList() { }

 

 1 // 通过头插法来插入指定元素
 2 private void linkFirst(E e) {  3     // 获取当前首结点引用
 4     final Node<E> f = first;  5     // 创建新结点
 6     final Node<E> newNode = new Node<>(null, e, f);  7     // 新结点设为首结点
 8     first = newNode;  9     // 如果插入前链表无结点,则新结点设为尾结点 10     // 否则,新结点设为当前首结点的前驱结点
11     if (f == null) 12         last = newNode; 13     else
14         f.prev = newNode; 15     // 元素数量+1
16     size++; 17     modCount++; 18 }

 

 1 // 通过尾插法来插入指定元素
 2 void linkLast(E e) {  3     // 获取当前尾结点引用
 4     final Node<E> l = last;  5     // 创建新结点
 6     final Node<E> newNode = new Node<>(l, e, null);  7     // 新结点设为尾结点
 8     last = newNode;  9     // 如果插入前链表无结点,则新结点设为首结点 10     // 否则,新结点设为当前尾结点的后继结点
11     if (l == null) 12         first = newNode; 13     else
14         l.next = newNode; 15     // 元素数量+1
16     size++; 17     modCount++; 18 }

 

 1 // 在指定非空结点前插入指定元素
 2 void linkBefore(E e, Node<E> succ) {  3     // assert succ != null;  4     // 获取指定非空结点的前驱结点引用
 5     final Node<E> pred = succ.prev;  6     // 创建新结点
 7     final Node<E> newNode = new Node<>(pred, e, succ);  8     // 新结点设为指定非空结点的前驱结点
 9     succ.prev = newNode; 10     // 如果指定非空结点的原来前驱结点为空,则新结点设为首结点 11     // 否则,新结点设为指定非空结点的原来前驱结点的后继结点
12     if (pred == null) 13         first = newNode; 14     else
15         pred.next = newNode; 16     // 元素数量+1
17     size++; 18     modCount++; 19 }

 

 1 // 删除首结点,返回存储的元素
 2 private E unlinkFirst(Node<E> f) {  3     // assert f == first && f != null;  4     // 获取首结点存储的元素
 5     final E element = f.item;  6     // 获取首结点的后继结点
 7     final Node<E> next = f.next;  8     // 删除首结点
 9     f.item = null; 10     f.next = null; // help GC 11     // 原来首结点的后继结点设为首结点
12     first = next; 13     // 如果原来首结点的后继结点为空,则尾结点设为null 14     // 否则,原来首结点的后继结点的前驱结点设为null
15     if (next == null) 16         last = null; 17     else
18         next.prev = null; // help GC 19     // 元素数量-1
20     size--; 21     modCount++; 22     // 返回原来首结点存储的元素
23     return element; 24 }

 

 1 // 删除尾结点,返回存储的元素
 2 private E unlinkLast(Node<E> l) {  3     // assert l == last && l != null;  4     // 获取尾结点存储的元素
 5     final E element = l.item;  6     // 获取尾结点的前驱结点
 7     final Node<E> prev = l.prev;  8     // 删除尾结点
 9     l.item = null; 10     l.prev = null; // help GC 11     // 原来尾结点的前驱结点设为尾结点
12     last = prev; 13     // 如果原来尾结点的前驱结点为空,则首结点设为null 14     // 否则,原来尾结点的前驱结点的后继结点设为null
15     if (prev == null) 16         first = null; 17     else
18         prev.next = null; 19     // 元素数量-1
20     size--; 21     modCount++; 22     // 返回原来尾结点存储的元素
23     return element; 24 }

 

 1 // 删除指定非空结点,返回存储的元素
 2 E unlink(Node<E> x) {  3     // assert x != null;  4     // 获取指定非空结点存储的元素
 5     final E element = x.item;  6     // 获取指定非空结点的后继结点
 7     final Node<E> next = x.next;  8     // 获取指定非空结点的前驱结点
 9     final Node<E> prev = x.prev; 10     
11     // 如果指定非空结点的前驱结点为空,则指定非空结点的后继结点设为首结点 12     // 否则,指定非空结点的后继结点设为指定非空结点的前驱结点的后继结点, 13     // 指定非空结点的前驱结点设为null
14     if (prev == null) { 15         first = next; 16     } else { 17         prev.next = next; 18         x.prev = null; 19  } 20     
21     // 如果指定非空结点的后继结点为空,则指定非空结点的前驱结点设为尾结点 22     // 否则,指定非空结点的前驱结点设为指定非空结点的后继结点的前驱结点, 23     // 指定非空结点的后继结点设为null
24     if (next == null) { 25         last = prev; 26     } else { 27         next.prev = prev; 28         x.next = null; 29  } 30 
31     // 指定非空结点存储的元素设为null
32     x.item = null; 33     // 元素数量-1
34     size--; 35     modCount++; 36     // 返回指定非空结点存储的元素
37     return element; 38 }

 

 1 // 获取首结点存储的元素
 2 public E getFirst() {  3     // 获取首结点引用
 4     final Node<E> f = first;  5     // 如果首结点为空,则抛出无该元素异常
 6     if (f == null)  7         throw new NoSuchElementException();  8     // 返回首结点存储的元素
 9     return f.item; 10 }

 

 1 // 获取首结点存储的元素
 2 public E getFirst() {  3     // 获取首结点引用
 4     final Node<E> f = first;  5     // 如果首结点为空,则抛出无该元素异常
 6     if (f == null)  7         throw new NoSuchElementException();  8     // 返回首结点存储的元素
 9     return f.item; 10 }

 

 1 // 获取尾结点存储的元素
 2 public E getLast() {  3     // 获取尾结点引用
 4     final Node<E> l = last;  5     // 如果尾结点为空,则抛出无该元素异常
 6     if (l == null)  7         throw new NoSuchElementException();  8     // 返回尾结点存储的元素
 9     return l.item; 10 }

 

 1 // 删除首结点,返回存储的元素
 2 public E removeFirst() {  3     // 获取首结点引用
 4     final Node<E> f = first;  5     // 如果首结点为空,则抛出无该元素异常
 6     if (f == null)  7         throw new NoSuchElementException();  8     // 删除首结点,返回存储的元素
 9     return unlinkFirst(f); 10 }

 

 1 // 删除尾结点,返回存储的元素
 2 public E removeLast() {  3     // 获取尾结点引用
 4     final Node<E> l = last;  5     // 如果尾结点为空,则抛出无该元素异常
 6     if (l == null)  7         throw new NoSuchElementException();  8     // 删除尾结点,返回存储的元素
 9     return unlinkLast(l); 10 }

 

// 头部插入指定元素
public void addFirst(E e) { // 通过头插法来插入指定元素
 linkFirst(e); }

 

// 尾部插入指定元素
public void addLast(E e) { // 通过尾插法来插入指定元素
 linkLast(e); }

 

// 判断是否包含指定元素
public boolean contains(Object o) { return indexOf(o) != -1; }

 

// 获取元素数量
public int size() { return size; }

 

1 // 插入指定元素,返回操作结果
2 public boolean add(E e) { 3     // 通过尾插法来插入指定元素
4  linkLast(e); 5     return true; 6 }

 

 1 // 删除顺序下首次出现的指定元素,返回操作结果
 2 public boolean remove(Object o) {  3     // 遍历链表,查找到指定元素后删除该结点,返回true
 4     if (o == null) {  5         for (Node<E> x = first; x != null; x = x.next) {  6             if (x.item == null) {  7  unlink(x);  8                 return true;  9  } 10  } 11     } else { 12         for (Node<E> x = first; x != null; x = x.next) { 13             if (o.equals(x.item)) { 14  unlink(x); 15                 return true; 16  } 17  } 18  } 19     // 查找失败
20     return false; 21 }

 

 1 // 删除顺序下首次出现的指定元素,返回操作结果
 2 public boolean remove(Object o) {  3     // 遍历链表,查找到指定元素后删除该结点,返回true
 4     if (o == null) {  5         for (Node<E> x = first; x != null; x = x.next) {  6             if (x.item == null) {  7  unlink(x);  8                 return true;  9  } 10  } 11     } else { 12         for (Node<E> x = first; x != null; x = x.next) { 13             if (o.equals(x.item)) { 14  unlink(x); 15                 return true; 16  } 17  } 18  } 19     // 查找失败
20     return false; 21 }

 

 1 // 删除所有元素
 2 public void clear() {  3     // Clearing all of the links between nodes is "unnecessary", but:  4     // - helps a generational GC if the discarded nodes inhabit  5     // more than one generation  6     // - is sure to free memory even if there is a reachable Iterator  7     // 遍历链表,删除所有结点
 8     for (Node<E> x = first; x != null; ) {  9         Node<E> next = x.next; 10         x.item = null; 11         x.next = null; 12         x.prev = null; 13         x = next; 14  } 15     // 首尾结点置空
16     first = last = null; 17     // 元素数量置0
18     size = 0; 19     modCount++; 20 }

 

1 // 获取指定位置的元素
2 public E get(int index) { 3     // 判断指定位置是否合法
4  checkElementIndex(index); 5     // 返回指定位置的元素
6     return node(index).item; 7 }

 

 1 // 修改指定位置的元素,返回旧元素
 2 public E set(int index, E element) {  3     // 判断指定位置是否合法
 4  checkElementIndex(index);  5     // 获取指定位置的结点
 6     Node<E> x = node(index);  7     // 获取该结点存储的元素
 8     E oldVal = x.item;  9     // 修改该结点存储的元素
10     x.item = element; 11     // 返回该结点存储的旧元素
12     return oldVal; 13 }

 

 1 // 在指定位置前插入指定元素
 2 public void add(int index, E element) {  3     // 判断指定位置是否合法
 4  checkPositionIndex(index);  5     
 6     // 如果指定位置在尾部,则通过尾插法来插入指定元素  7     // 否则,在指定位置的结点前面插入指定元素
 8     if (index == size)  9  linkLast(element); 10     else
11  linkBefore(element, node(index)); 12 }

 

1 // 删除指定位置的元素,返回旧元素
2 public E remove(int index) { 3     // 判断指定位置是否合法
4  checkElementIndex(index); 5     // 删除指定位置的结点,返回旧元素
6     return unlink(node(index)); 7 }

 

// 判断指定位置是否合法
private boolean isElementIndex(int index) { return index >= 0 && index < size; }

 

// 判断迭代器遍历时或插入元素时指定位置是否合法
private boolean isPositionIndex(int index) { return index >= 0 && index <= size; }

 

// 获取越界异常信息
private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; }

 

// 判断指定位置是否合法
private void checkElementIndex(int index) { if (!isElementIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }

 

// 判断指定位置是否合法
private void checkPositionIndex(int index) { if (!isPositionIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }

 

 1 // 获取指定下标的结点,index从0开始
 2 Node<E> node(int index) {  3     // assert isElementIndex(index);  4     // 如果指定下标<一半元素数量,则从首结点开始遍历  5     // 否则,从尾结点开始遍历
 6     if (index < (size >> 1)) {  7         Node<E> x = first;  8         for (int i = 0; i < index; i++)  9             x = x.next; 10         return x; 11     } else { 12         Node<E> x = last; 13         for (int i = size - 1; i > index; i--) 14             x = x.prev; 15         return x; 16  } 17 }

 

  Search Operations

 1 // 获取顺序下首次出现指定元素的位置  2 // 如果返回结果是-1,则表示不存在该元素
 3 public int indexOf(Object o) {  4     // 遍历链表,顺序查找指定元素
 5     int index = 0;  6     if (o == null) {  7         for (Node<E> x = first; x != null; x = x.next) {  8             if (x.item == null)  9                 return index; 10             index++; 11  } 12     } else { 13         for (Node<E> x = first; x != null; x = x.next) { 14             if (o.equals(x.item)) 15                 return index; 16             index++; 17  } 18  } 19     // 查找失败
20     return -1; 21 }

 

 1 // 获取逆序下首次出现指定元素的位置  2 // 如果返回结果是-1,则表示不存在该元素
 3 public int lastIndexOf(Object o) {  4     // 遍历链表,逆序查找指定元素
 5     int index = size;  6     if (o == null) {  7         for (Node<E> x = last; x != null; x = x.prev) {  8             index--;  9             if (x.item == null) 10                 return index; 11  } 12     } else { 13         for (Node<E> x = last; x != null; x = x.prev) { 14             index--; 15             if (o.equals(x.item)) 16                 return index; 17  } 18  } 19     // 查找失败
20     return -1; 21 }

 

  Queue operations

1 // 获取首元素
2 public E peek() { 3     // 获取首结点引用
4     final Node<E> f = first; 5     // 如果首结点为空,则返回null 6     // 否则,返回首结点存储的元素
7     return (f == null) ? null : f.item; 8 }

 

// 获取首元素
public E element() { // 返回首结点存储的元素
    return getFirst(); }

 

1 // 获取并删除首元素
2 public E poll() { 3     // 获取首结点引用
4     final Node<E> f = first; 5     // 如果首结点为空,则返回null 6     // 否则,删除首结点,返回首结点存储的元素
7     return (f == null) ? null : unlinkFirst(f); 8 }

 

// 获取并删除首元素
public E remove() { // 删除首结点,返回首结点存储的元素
    return removeFirst(); }

 

// 尾部插入指定元素,返回操作结果
public boolean offer(E e) { // 通过尾插法插入指定元素,返回操作结果
    return add(e); }

 

  Deque operations

1 // 头部插入指定元素,返回操作结果
2 public boolean offerFirst(E e) { 3     // 通过头插法来插入指定元素
4  addFirst(e); 5     // 操作成功
6     return true; 7 }

 

1 // 尾部插入指定元素,返回操作结果
2 public boolean offerLast(E e) { 3     // 通过尾插法来插入指定元素
4  addLast(e); 5     // 操作成功
6     return true; 7 }

 

1 // 获取首元素
2 public E peekFirst() { 3     // 获取首结点引用
4     final Node<E> f = first; 5     // 如果首结点为空,则返回null 6     // 否则,返回首结点存储的元素
7     return (f == null) ? null : f.item; 8  }

 

1 // 获取尾元素
2 public E peekLast() { 3     // 获取尾结点引用
4     final Node<E> l = last; 5     // 如果尾结点为空,则返回null 6     // 否则,返回尾结点存储的元素
7     return (l == null) ? null : l.item; 8 }

 

1 // 获取并删除首元素
2 public E pollFirst() { 3     // 获取首结点引用
4     final Node<E> f = first; 5     // 如果首结点为空,则返回null 6     // 否则,删除首结点,返回首结点存储的元素
7     return (f == null) ? null : unlinkFirst(f); 8 }

 

1 // 获取并删除尾元素
2 public E pollLast() { 3     // 获取尾结点引用
4     final Node<E> l = last; 5     // 如果尾结点为空,则返回null 6     // 否则,删除尾结点,返回尾结点存储的元素
7     return (l == null) ? null : unlinkLast(l); 8 }

 

// 头部插入指定元素
public void push(E e) { // 通过头插法来插入指定元素
 addFirst(e); }

 

// 获取并删除首元素
public E pop() { // 删除首结点,返回首结点存储的元素
    return removeFirst(); }

 

// 删除顺序下首次出现的指定元素,返回操作结果
public boolean removeFirstOccurrence(Object o) { // 删除顺序下首次出现的指定元素对应的结点,返回操作结果
    return remove(o); }

 

 1 // 删除逆序下首次出现的指定元素,返回操作结果
 2 public boolean removeLastOccurrence(Object o) {  3     // 遍历链表,从尾结点开始查找指定元素  4     // 如果查找成功,删除该结点,返回true
 5     if (o == null) {  6         for (Node<E> x = last; x != null; x = x.prev) {  7             if (x.item == null) {  8  unlink(x);  9                 return true; 10  } 11  } 12     } else { 13         for (Node<E> x = last; x != null; x = x.prev) { 14             if (o.equals(x.item)) { 15  unlink(x); 16                 return true; 17  } 18  } 19  } 20     // 查找失败
21     return false; 22 }

 

 1 // 链表结点类
 2 private static class Node<E> {  3     // 存储的元素
 4  E item;  5     // 后继结点
 6     Node<E> next;  7     // 前驱结点
 8     Node<E> prev;  9 
10     // 前驱结点、存储的元素和后继结点作为参数的构造方法
11     Node(Node<E> prev, E element, Node<E> next) { 12         this.item = element; 13         this.next = next; 14         this.prev = prev; 15  } 16 }

 

1 // 父类克隆方法
2 @SuppressWarnings("unchecked") 3 private LinkedList<E> superClone() { 4     try { 5         return (LinkedList<E>) super.clone(); 6     } catch (CloneNotSupportedException e) { 7         throw new InternalError(e); 8  } 9 }

 

 1 // 克隆,浅拷贝
 2 public Object clone() {  3     LinkedList<E> clone = superClone();  4 
 5     // Put clone into "virgin" state  6     // 链表初始化
 7     clone.first = clone.last = null;  8     clone.size = 0;  9     clone.modCount = 0; 10 
11     // Initialize clone with our elements 12     // 插入结点
13     for (Node<E> x = first; x != null; x = x.next) 14  clone.add(x.item); 15 
16     // 返回克隆后的对象引用
17     return clone; 18 }

 

// 序列化版本号
private static final long serialVersionUID = 876323262645176354L;

 

 1 // 序列化
 2 private void writeObject(java.io.ObjectOutputStream s)  3     throws java.io.IOException {  4     // Write out any hidden serialization magic  5     // 默认序列化
 6  s.defaultWriteObject();  7 
 8     // Write out size  9     // 写入元素数量
10  s.writeInt(size); 11 
12     // Write out all elements in the proper order. 13     // 遍历链表,写入所有元素
14     for (Node<E> x = first; x != null; x = x.next) 15  s.writeObject(x.item); 16 }

 

 1 // 反序列化
 2 @SuppressWarnings("unchecked")  3 private void readObject(java.io.ObjectInputStream s)  4     throws java.io.IOException, ClassNotFoundException {  5     // Read in any hidden serialization magic  6     // 默认反序列化
 7  s.defaultReadObject();  8 
 9     // Read in size 10     // 读取元素数量
11     int size = s.readInt(); 12 
13     // Read in all elements in the proper order. 14     // 遍历链表,读取所有元素并尾部插入
15     for (int i = 0; i < size; i++) 16  linkLast((E)s.readObject()); 17 }

 

  参考资料

  JDK_API_1_6_zh_CN.CHM