JDK 1.8 源码解析 LinkedList

Posted wjq2017

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK 1.8 源码解析 LinkedList相关的知识,希望对你有一定的参考价值。

 

package java.util;

 

// LinkedList继承了AbstractSequentialList
// 实现了List、Deque、Cloneable和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 public LinkedList(Collection<? extends E> c) {
3     // 调用无参构造方法
4     this();
5     // 尾部插入集合中的所有元素
6     addAll(c);
7 }

 

 1 // 使用头插法插入指定元素
 2 private void linkFirst(E e) {
 3     final Node<E> f = first;
 4     // 创建新的首结点
 5     final Node<E> newNode = new Node<>(null, e, f);
 6     // 修改首结点
 7     first = newNode;
 8     // 如果插入的是第一个结点
 9     if (f == null)
10         last = newNode;
11     else
12         f.prev = newNode;
13     // 元素数量自增
14     size++;
15     modCount++;
16 }

 

 1 // 使用尾插法插入指定元素
 2 void linkLast(E e) {
 3     final Node<E> l = last;
 4     // 创建新的尾结点
 5     final Node<E> newNode = new Node<>(l, e, null);
 6     // 修改尾结点
 7     last = newNode;
 8     // 如果插入的是第一个结点
 9     if (l == null)
10         first = newNode;
11     else
12         l.next = newNode;
13     // 元素数量自增
14     size++;
15     modCount++;
16 }

 

 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     if (pred == null)
12         first = newNode;
13     else
14         pred.next = newNode;
15     // 元素数量自增
16     size++;
17     modCount++;
18 }

 

 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     f.item = null;
 9     f.next = null; // help GC
10     // 修改首结点
11     first = next;
12     // 如果后继结点为空
13     if (next == null)
14         last = null;
15     else
16         next.prev = null; // help GC
17     // 元素数量自减
18     size--;
19     modCount++;
20     // 返回存储的元素
21     return element;
22 }

 

 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     l.item = null;
 9     l.prev = null; // help GC
10     // 修改尾结点
11     last = prev;
12     // 如果前驱结点为空
13     if (prev == null)
14         first = null;
15     else
16         prev.next = null;
17     // 元素数量自减
18     size--;
19     modCount++;
20     // 返回存储的元素
21     return element;
22 }

 

 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     if (prev == null) {
13         first = next;
14     } else {
15         prev.next = next;
16         x.prev = null;
17     }
18     
19     // 如果后继结点为空
20     if (next == null) {
21         last = prev;
22     } else {
23         next.prev = prev;
24         x.next = null;
25     }
26 
27     // 存储的元素置空
28     x.item = null;
29     // 元素数量自减
30     size--;
31     modCount++;
32     // 返回存储的元素
33     return element;
34 }

 

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

 

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

 

1 // 删除首元素
2 public E removeFirst() {
3     final Node<E> f = first;
4     // 如果首结点为空
5     if (f == null)
6         throw new NoSuchElementException();
7     // 删除首结点
8     return unlinkFirst(f);
9 }

 

1 // 删除尾元素
2 public E removeLast() {
3     final Node<E> l = last;
4     // 如果尾结点为空
5     if (l == null)
6         throw new NoSuchElementException();
7     // 删除尾结点
8     return unlinkLast(l);
9 }

 

// 头部插入指定元素
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     // 如果指定元素为空
 4     if (o == null) {
 5         // 遍历链表,查找null
 6         for (Node<E> x = first; x != null; x = x.next) {
 7             if (x.item == null) {
 8                 unlink(x);
 9                 return true;
10             }
11         }
12     } else {
13         for (Node<E> x = first; x != null; x = x.next) {
14             if (o.equals(x.item)) {
15                 unlink(x);
16                 return true;
17             }
18         }
19     }
20     return false;
21 }

 

// 尾部插入集合中的所有元素
public boolean addAll(Collection<? extends E> c) {
    return addAll(size, c);
}

 

 1 // 在指定位置前插入集合中的所有元素
 2 public boolean addAll(int index, Collection<? extends E> c) {
 3     // 判断插入位置是否合法
 4     checkPositionIndex(index);
 5 
 6     // 获取集合对应的数组
 7     Object[] a = c.toArray();
 8     // 获取集合元素数量
 9     int numNew = a.length;
10     // 如果集合中没有元素,则插入失败
11     if (numNew == 0)
12         return false;
13 
14     // pred表示前驱结点
15     // succ表示后继结点
16     Node<E> pred, succ;
17     // 如果指定位置为末尾
18     if (index == size) {
19         succ = null;
20         pred = last;
21     } else {
22         succ = node(index);
23         pred = succ.prev;
24     }
25 
26     // 遍历集合中所有元素
27     for (Object o : a) {
28         // 强制类型转换
29         @SuppressWarnings("unchecked") E e = (E) o;
30         // 创建新的链表结点
31         Node<E> newNode = new Node<>(pred, e, null);
32         // 如果前驱结点为null
33         if (pred == null)
34             first = newNode;
35         else
36             pred.next = newNode;
37         pred = newNode;
38     }
39 
40     // 如果后继结点为null
41     if (succ == null) {
42         last = pred;
43     } else {
44         // 处理插入的最后一个结点的索引关系
45         pred.next = succ;
46         succ.prev = pred;
47     }
48 
49     // 元素数量加上集合中的元素数量
50     size += numNew;
51     modCount++;
52     // 插入成功
53     return true;
54 }

 

 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     for (Node<E> x = first; x != null; ) {
 8         Node<E> next = x.next;
 9         x.item = null;
10         x.next = null;
11         x.prev = null;
12         x = next;
13     }
14     // 首尾结点置空
15     first = last = null;
16     // 元素数量置0
17     size = 0;
18     modCount++;
19 }

 

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     if (index == size)
 8         linkLast(element);
 9     else
10         linkBefore(element, node(index));
11 }

 

// 删除指定位置的元素
public E remove(int index) {
    checkElementIndex(index);
    return unlink(node(index));
}

 

// 判断元素位置是否合法
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     if (index < (size >> 1)) {
 6         Node<E> x = first;
 7         for (int i = 0; i < index; i++)
 8             x = x.next;
 9         return x;
10     } else {
11         Node<E> x = last;
12         for (int i = size - 1; i > index; i--)
13             x = x.prev;
14         return x;
15     }
16 }

 

  Search Operations

 1 // 查找第一次出现指定元素的位置,如果返回结果是-1,则表示不存在该元素
 2 public int indexOf(Object o) {
 3     int index = 0;
 4     // 如果指定元素为null
 5     if (o == null) {
 6         // 遍历链表
 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     return -1;
20 }

 

 1 // 查找最后一次出现指定元素的位置,如果返回结果是-1,则表示不存在该元素
 2 public int lastIndexOf(Object o) {
 3     int index = size;
 4     // 如果指定元素为null
 5     if (o == null) {
 6         // 遍历链表
 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     return -1;
20 }

 

  Queue operations

// 获取首元素
public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}

 

// 获取首元素
public E element() {
    return getFirst();
}

 

// 获取并删除首元素
public E poll() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}

 

// 获取并删除首元素
public E remove() {
    return removeFirst();
}

 

// 尾部插入指定元素
public boolean offer(E e) {
    return add(e);
}

 

  Deque operations

// 头部插入指定元素
public boolean offerFirst(E e) {
    addFirst(e);
    return true;
}

 

// 尾部插入指定元素
public boolean offerLast(E e) {
    addLast(e);
    return true;
}

 

// 获取首元素
public E peekFirst() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
 }

 

// 获取尾元素
public E peekLast() {
    final Node<E> l = last;
    return (l == null) ? null : l.item;
}

 

// 获取并删除首元素
public E pollFirst() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}

 

// 获取并删除尾元素
public E pollLast() {
    final Node<E> l = last;
    return (l == null) ? null : unlinkLast(l);
}

 

// 头部插入指定元素
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     if (o == null) {
 4         for (Node<E> x = last; x != null; x = x.prev) {
 5             if (x.item == null) {
 6                 unlink(x);
 7                 return true;
 8             }
 9         }
10     } else {
11         for (Node<E> x = last; x != null; x = x.prev) {
12             if (o.equals(x.item)) {
13                 unlink(x);
14                 return true;
15             }
16         }
17     }
18     return false;
19 }

 

 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 }

 

1 // 获取以原顺序包含该链表中所有元素的数组
2 public Object[] toArray() {
3     Object[] result = new Object[size];
4     int i = 0;
5     // 遍历链表
6     for (Node<E> x = first; x != null; x = x.next)
7         result[i++] = x.item;
8     return result;
9 }

 

 1 // 获取以原顺序包含该链表中所有元素的数组,返回数组的运行时类型为指定数组的类型
 2 @SuppressWarnings("unchecked")
 3 public <T> T[] toArray(T[] a) {
 4     // 如果原数组不足以存储链表中的所有元素
 5     if (a.length < size)
 6         a = (T[])java.lang.reflect.Array.newInstance(
 7                             a.getClass().getComponentType(), size);
 8     int i = 0;
 9     Object[] result = a;
10     // 遍历链表
11     for (Node<E> x = first; x != null; x = x.next)
12         result[i++] = x.item;
13 
14     // 如果原数组有空余
15     if (a.length > size)
16         a[size] = null;
17 
18     // 返回结果数组
19     return a;
20 }

 

// 序列化版本号
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 1.8 源码解析 LinkedList的主要内容,如果未能解决你的问题,请参考以下文章

JDK1.8JDK1.8集合源码阅读——LinkedList

JDK源码阅读:LinkedList源码解析

LinkedList源码解析(基于JDK1.7)

LinkedList源码解析(基于JDK1.7)

JDK 1.8 源码解析 PriorityQueue

LinkedList源码解析(JDK1.8)