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 }

原文地址:https://www.cnblogs.com/WJQ2017/p/8280702.html

时间: 2024-10-09 05:54:51

JDK 1.8 源码解析 LinkedList的相关文章

jdk下httpserver源码解析

在写这篇博客之前我查了很久发现全网都没有一篇写httpserver源码解析的 所以今天就由我来为大家解析一下httpserver的源码.(这里我会去掉其中的https部分的源码,只讲http部分,对httpserver中https的实现感兴趣的读者可以尝试自己去阅读,这部分并不复杂) 第一次在没有参考资料的情况下写这么长一篇源码解析,可能会有很多错误和讲不清楚的地方,希望大家尽量指出来. 本文链接 https://www.cnblogs.com/fatmanhappycode/p/1261442

JDK核心JAVA源码解析(1) - Object

想写这个系列很久了,对自己也是个总结与提高.原来在学JAVA时,那些JAVA入门书籍会告诉你一些规律还有法则,但是用的时候我们一般很难想起来,因为我们用的少并且不知道为什么.知其所以然方能印象深刻并学以致用. 首先我们从所有类的父类Object开始: 1. Object类 (1)hashCode方法和equals方法 public native int hashCode(); public boolean equals(Object obj) { return (this == obj); }

JDK 1.8 源码解析 String、StringBuilder和StringBuffer的异同

JDK提供了String.StringBuilder和StringBuffer这三个类来处理字符串,其中StringBuilder类是在JDK 1.5中新增的. 不同点如下: 1 是否有父类 String没有父类. // String类不能被继承 // 实现了Serializable.Comparable和CharSequence(字符序列)接口 public final class String implements java.io.Serializable, Comparable<Strin

JDK 1.8 源码解析 ConcurrentHashMap

JDK 1.7中ConcurrentHashMap 基本结构: 每一个segment都是一个HashEntry<K,V>[] table, table中的每一个元素本质上都是一个HashEntry的单向队列.比如table[3]为首结点,table[3]->next为结点1,之后为结点2,依次类推. 1 public class ConcurrentHashMap<K, V> extends AbstractMap<K, V> 2 implements Concu

JDK 1.8 源码解析 PriorityQueue

package java.util; public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable // 序列化版本号 private static final long serialVersionUID = -7720805057305804111L; // 默认初始容量 private static final int DEFAULT_INITIAL_CAPACITY

JDK 1.8 源码解析 HashSet

package java.util; // HashSet继承了AbstractSet,实现了Set.Cloneable和java.io.Serializable接口 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable // 序列化版本号 static final long serialVersionUID = -5024744

LinledList源码解析

LinkedList源码解析 LinkedList源码解析 简介 结构 内部类讲解 属性expectedModCount属性的讲解 主要方法讲解 --简介 LinkedList底层是使用双线链表来实现的,将数组添加到这个集合或者是从集合删除其实都是对双向链表增加节点和删除及节点的操作. LinkedList实现的类AbstractSequentialList中定义的modCount属性使得继承自它的集合不能够异步的进行合集的增加删除等等操作,即操作是线程不安全的. --结构 LinkedList

给jdk写注释系列之jdk1.6容器(2)-LinkedList源码解析

LinkedList是基于链表结构的一种List,在分析LinkedList源码前有必要对链表结构进行说明. 1.链表的概念 链表是由一系列非连续的节点组成的存储结构,简单分下类的话,链表又分为单向链表和双向链表,而单向/双向链表又可以分为循环链表和非循环链表,下面简单就这四种链表进行图解说明.           1.1.单向链表 单向链表就是通过每个结点的指针指向下一个结点从而链接起来的结构,最后一个节点的next指向null.      1. 2.单向循环链表           单向循环

给jdk写注释系列之jdk1.6容器(10)-Stack&amp;Vector源码解析

前面我们已经接触过几种数据结构了,有数组.链表.Hash表.红黑树(二叉查询树),今天再来看另外一种数据结构:栈. 什么是栈呢,我就不找它具体的定义了,直接举个例子,栈就相当于一个很窄的木桶,我们往木桶里放东西,往外拿东西时会发现,我们最开始放的东西在最底部,最先拿出来的是刚刚放进去的.所以,栈就是这么一种先进后出( First In Last Out,或者叫后进先出) 的容器,它只有一个口,在这个口放入元素,也在这个口取出元素. 栈最主要了两个动作就是入栈和出栈操作,其实还是很容易的明白的对不