java.util 
类 LinkedList<E>

java.lang.Objectjava.util.AbstractCollection<E>java.util.AbstractList<E>java.util.AbstractSequentialList<E>java.util.LinkedList<E>

List 接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。

除了实现 List 接口外,LinkedList 类还为在列表的开头及结尾 get、remove 和 insert 元素提供了统一的命名方法。这些操作允许将链接列表用作堆栈、队列或双端队列。

此类实现 Deque 接口,为 add、poll 提供先进先出队列操作,以及其他堆栈和双端队列操作。

所有操作都是按照双重链接列表的需要执行的。在列表中编索引的操作将从开头或结尾遍历列表(从靠近指定索引的一端)。

操作效率:大部分效率都是o(n)的

同步:

注意,此实现不是同步的。如果多个线程同时访问一个链接列表,而其中至少一个线程从结构上修改了该列表,则它必须 保持外部同步。(结构修改指添加或删除一个或多个元素的任何操作;仅设置元素的值不是结构修改。)这一般通过对自然封装该列表的对象进行同步操作来完成。如果不存在这样的对象,则应该使用 Collections.synchronizedList 方法来“包装”该列表。最好在创建时完成这一操作,以防止对列表进行意外的不同步访问,如下所示:

   List list = Collections.synchronizedList(new LinkedList(...));

iterator :

此类的 iterator 和 listIterator 方法返回的迭代器是快速失败 的:在迭代器创建之后,如果从结构上对列表进行修改,除非通过迭代器自身的 remove 或 add 方法,其他任何时间任何方式的修改,迭代器都将抛出 ConcurrentModificationException。因此,面对并发的修改,迭代器很快就会完全失败,而不冒将来不确定的时间任意发生不确定行为的风险。

注意,迭代器的快速失败行为不能得到保证,一般来说,存在不同步的并发修改时,不可能作出任何硬性保证。快速失败迭代器尽最大努力抛出 ConcurrentModificationException。因此,编写依赖于此异常的程序的方式是错误的,正确做法是:迭代器的快速失败行为应该仅用于检测程序错误。

构造方法摘要
LinkedList() 
          构造一个空列表。
LinkedList(Collection<? extends E> c) 
          构造一个包含指定 collection 中的元素的列表,这些元素按其 collection 的迭代器返回的顺序排列。
方法摘要
 boolean add(E e) 
          将指定元素添加到此列表的结尾。
 void add(int index, E element) 
          在此列表中指定的位置插入指定的元素。
 boolean addAll(Collection<? extends E> c) 
          添加指定 collection 中的所有元素到此列表的结尾,顺序是指定 collection 的迭代器返回这些元素的顺序。
 boolean addAll(int index, Collection<? extends E> c) 
          将指定 collection 中的所有元素从指定位置开始插入此列表。
 void addFirst(E e) 
          将指定元素插入此列表的开头。
 void addLast(E e) 
          将指定元素添加到此列表的结尾。
 void clear() 
          从此列表中移除所有元素。
 Object clone() 
          返回此 LinkedList 的浅表副本。
 boolean contains(Object o) 
          如果此列表包含指定元素,则返回 true。
 Iterator<E> descendingIterator() 
          返回以逆向顺序在此双端队列的元素上进行迭代的迭代器。
 E element() 
          获取但不移除此列表的头(第一个元素)。
 E get(int index) 
          返回此列表中指定位置处的元素。
 E getFirst() 
          返回此列表的第一个元素。
 E getLast() 
          返回此列表的最后一个元素。
 int indexOf(Object o) 
          返回此列表中首次出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
 int lastIndexOf(Object o) 
          返回此列表中最后出现的指定元素的索引,如果此列表中不包含该元素,则返回 -1。
 ListIterator<E> listIterator(int index) 
          返回此列表中的元素的列表迭代器(按适当顺序),从列表中指定位置开始。
 boolean offer(E e) 
          将指定元素添加到此列表的末尾(最后一个元素)。
 boolean offerFirst(E e) 
          在此列表的开头插入指定的元素。
 boolean offerLast(E e) 
          在此列表末尾插入指定的元素。
 E peek() 
          获取但不移除此列表的头(第一个元素)。
 E peekFirst() 
          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
 E peekLast() 
          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
 E poll() 
          获取并移除此列表的头(第一个元素)
 E pollFirst() 
          获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
 E pollLast() 
          获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
 E pop() 
          从此列表所表示的堆栈处弹出一个元素。
 void push(E e) 
          将元素推入此列表所表示的堆栈。
 E remove() 
          获取并移除此列表的头(第一个元素)。
 E remove(int index) 
          移除此列表中指定位置处的元素。
 boolean remove(Object o) 
          从此列表中移除首次出现的指定元素(如果存在)。
 E removeFirst() 
          移除并返回此列表的第一个元素。
 boolean removeFirstOccurrence(Object o) 
          从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。
 E removeLast() 
          移除并返回此列表的最后一个元素。
 boolean removeLastOccurrence(Object o) 
          从此列表中移除最后一次出现的指定元素(从头部到尾部遍历列表时)。
 E set(int index, E element) 
          将此列表中指定位置的元素替换为指定的元素。
 int size() 
          返回此列表的元素数。
 Object[] toArray() 
          返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组。
<T> T[]
toArray(T[] a) 
          返回以适当顺序(从第一个元素到最后一个元素)包含此列表中所有元素的数组;返回数组的运行时类型为指定数组的类型。
package java.util;
import java.util.function.Consumer;
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() {}/*** 通过一个集合初始化,元素顺序有这个集合的迭代器返回顺序决定* * @param c*            其元素将被放入此列表中的集合* @throws NullPointerException*             如果指定的集合是空的*/public LinkedList(Collection<? extends E> c) {// 调用无参构造this();// 添加所有的元素addAll(c);}/*** 头插,内部使用*/private void linkFirst(E e) {// 当前首结点final Node<E> f = first;// 构建新节点final Node<E> newNode = new Node<>(null, e, f);// 将newNode作为首节点first = newNode;// 如果原首节点为null,即原链表为null,则链表尾节点也设置为newNodeif (f == null)last = newNode;else                // 否则,原首节点的prev设置为newNodef.prev = newNode;size++;             // 长度+1modCount++; // 修改次数+1}/*** 尾插*/void linkLast(E e) {// 获取尾结点final Node<E> l = last;// 构建新节点final Node<E> newNode = new Node<>(l, e, null);// newNode作为尾节点last = newNode;// 如果原尾节点为null,即原链表为null,则链表首节点也设置为newNodeif (l == null)first = newNode;else    // 否则,原尾节点的next设置为newNodel.next = newNode;size++;modCount++;}/*** 在非空节点succ前插入节点值e*/void linkBefore(E e, Node<E> succ) {final Node<E> pred = succ.prev;// 构建新节点final Node<E> newNode = new Node<>(pred, e, succ);// 设置newNode为succ的前节点succ.prev = newNode;// 如果succ.prev为null,即succ为首节点,则将newNode设置为首节点if (pred == null)first = newNode;else        // 如果succ不是首节点pred.next = newNode;size++;modCount++;}/*** 删除首结点,返回存储的元素,内部使用*/private E unlinkFirst(Node<E> f) {// 获取首结点存储的元素final E element = f.item;// 获取首结点的后继结点final Node<E> next = f.next;// 删除首结点f.item = null;f.next = null; // 便于垃圾回收// 首结点后继结点设为首结点first = next;// 如果原来首结点的后继结点为空,则尾结点设为null// 否则,原来首结点的后继结点的前驱结点设为nullif (next == null)last = null;elsenext.prev = null;size--;modCount++;// 返回原来首结点存储的元素return element;}/*** 删除尾结点,返回存储的元素,内部使用*/private E unlinkLast(Node<E> l) {// 获取尾结点存储的元素final E element = l.item;// 获取尾结点的前驱结点final Node<E> prev = l.prev;// 删除尾结点l.item = null;l.prev = null; // help GC// 原来尾结点的前驱结点设为尾结点last = prev;// 如果原来尾结点的前驱结点为空,则首结点设为null// 否则,原来尾结点的前驱结点的后继结点设为nullif (prev == null)first = null;elseprev.next = null;size--;modCount++;// 返回原来尾结点存储的元素return element;}/*** 删除指定非空结点,返回存储的元素*/E unlink(Node<E> x) {// 获取指定非空结点存储的元素final E element = x.item;// 获取指定非空结点的后继结点final Node<E> next = x.next;// 获取指定非空结点的前驱结点final Node<E> prev = x.prev;/*** 如果指定非空结点的前驱结点为空,则指定非空结点的后继结点设为首结点 * 否则,指定非空结点的后继结点设为指定非空结点的前驱结点的后继结点,* 指定非空结点的前驱结点设为null*/if (prev == null) {first = next;} else {prev.next = next;x.prev = null;}/*** 如果指定非空结点的后继结点为空,则指定非空结点的前驱结点设为尾结点 * 否则,指定非空结点的前驱结点设为指定非空结点的后继结点的前驱结点,* 指定非空结点的后继结点设为null*/if (next == null) {last = prev;} else {next.prev = prev;x.next = null;}// 指定非空结点存储的元素设为nullx.item = null;size--;modCount++;// 返回指定非空结点存储的元素return element;}/*** 获取首结点存储的元素* * @return 首结点存储的元素* @throws NoSuchElementException*             如果链表为空*/public E getFirst() {// 获取首结点引用final Node<E> f = first;// 如果首结点为空,则抛出无该元素异常if (f == null)throw new NoSuchElementException();// 返回首结点存储的元素return f.item;}/*** 获取尾结点存储的元素* * @return 尾结点存储的元素* @throws NoSuchElementException*             如果链表为空*/public E getLast() {// 获取尾结点引用final Node<E> l = last;// 如果尾结点为空,则抛出无该元素异常if (l == null)throw new NoSuchElementException();// 返回尾结点存储的元素return l.item;}/*** 删除首结点,返回存储的元素* * @return 首结点存储的元素* @throws NoSuchElementException*             如果链表为空*/public E removeFirst() {// 获取首结点引用final Node<E> f = first;// 如果首结点为空,则抛出无该元素异常if (f == null)throw new NoSuchElementException();// 删除首结点,返回存储的元素return unlinkFirst(f);}/*** 删除尾结点,返回存储的元素* * @return 尾结点存储的元素* @throws NoSuchElementException*             如果链表为空*/public E removeLast() {// 获取尾结点引用final Node<E> l = last;// 如果尾结点为空,则抛出无该元素异常if (l == null)throw new NoSuchElementException();// 删除尾结点,返回存储的元素return unlinkLast(l);}/*** 头部插入指定元素* * @param e*            要添加的元素*/public void addFirst(E e) {// 通过头插法来插入指定元素linkFirst(e);}/*** 尾部插入指定元素,该方法等价于add()* * @param e*            the element to add*/public void addLast(E e) {linkLast(e);}/*** 判断是否包含指定元素* * @param o*            判断链表是否包含的元素* @return {@code true} 如果链表包含指定的元素*/public boolean contains(Object o) {// 返回指定元素的索引位置,不存在就返回-1,然后比较返回bool值return indexOf(o) != -1;}/*** 获取元素数量* * @return 元素数量*/public int size() {return size;}/*** 插入指定元素,返回操作结果,默认添加到末尾作为最后一个元素* * @param e*            要添加到此链表中的元素* @return {@code true} (as specified by {@link Collection#add})*/public boolean add(E e) {// 通过尾插法来插入指定元素linkLast(e);return true;}/*** 删除指定元素,默认从first节点开始,删除第一次出现的那个元素* * @param o*            要从该列表中删除的元素(如果存在)* @return {@code true} 如果这个列表包含指定的元素*/public boolean remove(Object o) {// 会根据是否为null分开处理。若值不是null,会用到对象的equals()方法if (o == null) {// 遍历链表,查找到指定元素后删除该结点,返回truefor (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) {unlink(x);return true;}}}// 查找失败return false;}/*** 将集合插入到链表尾部* * @param c*            包含要添加到此链表中的元素的集合* @return {@code true} 如果该链表因添加而改变* @throws NullPointerException*             如果指定的集合是空的*/public boolean addAll(Collection<? extends E> c) {return addAll(size, c);}/*** 将集合从指定位置开始插入* * @param index*            在哪个索引处前插入指定集合中的第一个元素* @param c*            包含要添加到此链表中的元素的集合* @return {@code true} 如果该链表因添加而改变* @throws IndexOutOfBoundsException*             {@inheritDoc}* @throws NullPointerException*             如果指定的集合是空的*/public boolean addAll(int index, Collection<? extends E> c) {// 检查索引是否正确(0<=index<=size)checkPositionIndex(index);// 得到元素数组Object[] a = c.toArray();// 得到元素个数int numNew = a.length;// 没有元素,返回falseif (numNew == 0)return false;// succ指向当前需要插入节点的位置,pred指向其前一个节点Node<E> pred, succ;// 末尾开始添加,当前节点后一个节点为null,前一个节点为尾节点if (index == size) {succ = null;pred = last;} else {    //当前位置的节点为指定位置的节点,前一个节点为要添加的节点的前一个节点succ = node(index);pred = succ.prev;}// 遍历数组并添加到列表中for (Object o : a) {@SuppressWarnings("unchecked") E e = (E) o;// “封装”一个新节点Node<E> newNode = new Node<>(pred, e, null);// 原链表为null,新插入的节点作为链表首节点if (pred == null)first = newNode;elsepred.next = newNode;    // 存在前节点,前节点向后指向新加的节点pred = newNode; // pred指针向后移动}// 从最后开始添加,则新节点成为尾节点if (succ == null) {last = pred;} else {pred.next = succ;   // 新节点向后指向之前得到的后续第一个节点succ.prev = pred;   // 后续的第一个节点也应改为向前指向最后一个添加的节点}size += numNew;modCount++;return true;}/*** 删除所有元素*/public void clear() {// 遍历链表,删除所有结点,方便gc回收垃圾for (Node<E> x = first; x != null; ) {Node<E> next = x.next;x.item = null;x.next = null;x.prev = null;x = next;}// 首尾结点置空first = last = null;// 元素数量置0size = 0;modCount++;}// 位置访问操作/*** 获取指定位置的元素* * @param index*            要返回的元素的索引* @return 该链表中指定位置的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public E get(int index) {// 判断指定位置是否合法checkElementIndex(index);// 返回指定位置的元素return node(index).item;}/*** 修改指定位置的元素,返回之前元素* * @param index*            要替换的元素的索引* @param element*            要存储在指定位置的元素* @return 之前在指定位置的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public E set(int index, E element) {// 判断指定位置是否合法checkElementIndex(index);// 获取指定位置的结点Node<E> x = node(index);// 获取该结点存储的元素E oldVal = x.item;// 修改该结点存储的元素x.item = element;// 返回该结点存储的之前的元素return oldVal;}/*** 在指定位置前插入指定元素* 头插法* @param index*            指定元素将被插入的索引* @param element*            要插入的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/public void add(int index, E element) {// 判断指定位置是否合法checkPositionIndex(index);// 如果指定位置在尾部,则通过尾插法来插入指定元素if (index == size)linkLast(element);else        // 如果指定位置不是尾部,则添加到指定位置前linkBefore(element, node(index));}/*** 删除指定位置的元素,返回之前元素* * @param index*            要删除的元素的索引* @return 之前在指定位置的元素* @throws IndexOutOfBoundsException*             {@inheritDoc}*/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;}/*** 判断指定位置是否合法* * @param index*/private void checkElementIndex(int index) {if (!isElementIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 判断指定位置是否合法* * @param index*/private void checkPositionIndex(int index) {if (!isPositionIndex(index))throw new IndexOutOfBoundsException(outOfBoundsMsg(index));}/*** 获取指定下标的结点*/Node<E> node(int 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;}}// 查询操作/*** 获取首次出现指定元素的位置 -1表示不存在* 同样是根据是否为null进行区分* @param o*            要查找的元素* @return the index of the first occurrence of the specified element in*         this list, or -1 if this list does not contain the element*/public int indexOf(Object o) {int index = 0;if (o == null) {// 遍历链表,顺序查找指定元素for (Node<E> x = first; x != null; x = x.next) {if (x.item == null)return index;index++;}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item))return index;index++;}}return -1;}/*** 获取逆序下首次出现指定元素的位置 -1表示不存在* * @param o*            要查找的元素* @return the index of the last occurrence of the specified element in this*         list, or -1 if this list does not contain the element*/public int lastIndexOf(Object o) {int index = size;if (o == null) {// 遍历链表,逆序查找指定元素for (Node<E> x = last; x != null; x = x.prev) {index--;if (x.item == null)return index;}} else {for (Node<E> x = last; x != null; x = x.prev) {index--;if (o.equals(x.item))return index;}}return -1;}// 队列操作/*** 出队(从前端),获得第一个元素,不存在会返回null,不会删除元素(节点) 获取首元素* * @return the head of this list, or {@code null} 如果链表为空* @since 1.5*/public E peek() {final Node<E> f = first;// 如果首结点为空,则返回null// 否则,返回首结点存储的元素return (f == null) ? null : f.item;}/*** 出队(从前端),不删除元素,若为null会抛出异常而不是返回null 获取首元素* * @return the head of this list* @throws NoSuchElementException*             如果链表为空* @since 1.5*/public E element() {// 返回首结点存储的元素return getFirst();}/*** 出队(从前端),如果不存在会返回null,存在的话会返回值并移除这个元素(节点) 获取并删除首元素* * @return the head of this list, or {@code null} 如果链表为空* @since 1.5*/public E poll() {// 获取首结点引用final Node<E> f = first;// 如果首结点为空,则返回null// 否则,删除首结点,返回首结点存储的元素return (f == null) ? null : unlinkFirst(f);}/*** 出队(从前端),如果不存在会抛出异常而不是返回null,存在的话会返回值并移除这个元素(节点) 获取并删除首元素* * @return the head of this list* @throws NoSuchElementException*             如果链表为空* @since 1.5*/public E remove() {// 删除首结点,返回首结点存储的元素return removeFirst();}/*** 入队(从后端),始终返回true* * 链表不会溢出* @param e*            the element to add* @return {@code true} (as specified by {@link Queue#offer})* @since 1.5*/public boolean offer(E e) {// 通过尾插法插入指定元素,返回操作结果return add(e);}// 双端队列操作/*** 入队(从前端),始终返回true* * @param e*            要插入的元素* @return {@code true} (as specified by {@link Deque#offerFirst})* @since 1.6*/public boolean offerFirst(E e) {// 通过头插法来插入指定元素addFirst(e);return true;}/*** 入队(从后端),始终返回true* * @param e*            要插入的元素* @return {@code true} (as specified by {@link Deque#offerLast})* @since 1.6*/public boolean offerLast(E e) {// 通过尾插法来插入指定元素addLast(e);return true;}/*** 出队(从前端),获得第一个元素,不存在会返回null,不会删除元素(节点)* * @return the first element of this list, or {@code null} 如果链表为空* @since 1.6*/public E peekFirst() {// 获取首结点引用final Node<E> f = first;// 如果首结点为空,则返回null// 否则,返回首结点存储的元素return (f == null) ? null : f.item;}/*** 出队(从后端),获得最后一个元素,不存在会返回null,不会删除元素(节点)* * @return the last element of this list, or {@code null} 如果链表为空* @since 1.6*/public E peekLast() {// 获取尾结点引用final Node<E> l = last;// 如果尾结点为空,则返回null// 否则,返回尾结点存储的元素return (l == null) ? null : l.item;}/*** 出队(从前端),获得第一个元素,不存在会返回null,会删除元素(节点)* * @return the first element of this list, or {@code null} if this list is*         empty* @since 1.6*/public E pollFirst() {// 获取首结点引用final Node<E> f = first;// 如果首结点为空,则返回null// 否则,删除首结点,返回首结点存储的元素return (f == null) ? null : unlinkFirst(f);}/*** 出队(从后端),获得最后一个元素,不存在会返回null,会删除元素(节点)* * @return the last element of this list, or {@code null} if this list is*         empty* @since 1.6*/public E pollLast() {// 获取尾结点引用final Node<E> l = last;// 如果尾结点为空,则返回null// 否则,删除尾结点,返回尾结点存储的元素return (l == null) ? null : unlinkLast(l);}/*** 入栈,从前面添加* * @param e*            the element to push* @since 1.6*/public void push(E e) {// 通过头插法来插入指定元素addFirst(e);}/*** 出栈,返回栈顶元素,从前面移除(会删除)* * @return the element at the front of this list (which is the top of the*         stack represented by this list)* @throws NoSuchElementException*             如果链表为空* @since 1.6*/public E pop() {// 删除首结点,返回首结点存储的元素return removeFirst();}/*** 删除顺序下首次出现的指定元素,返回操作结果* * @param o*            要从该列表中删除的元素(如果存在)* @return {@code true} 如果链表包含指定的元素* @since 1.6*/public boolean removeFirstOccurrence(Object o) {// 删除顺序下首次出现的指定元素对应的结点,返回操作结果return remove(o);}/*** 删除逆序下首次出现的指定元素,返回操作结果* * @param o*            要从该列表中删除的元素(如果存在)* @return {@code true} 如果链表包含指定的元素* @since 1.6*/public boolean removeLastOccurrence(Object o) {// 由于LinkedList中允许存放null,因此下面通过两种情况来分别处理if (o == null) {// 遍历链表,从尾结点开始查找指定元素// 如果查找成功,删除该结点,返回truefor (Node<E> x = last; x != null; x = x.prev) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = last; x != null; x = x.prev) {if (o.equals(x.item)) {unlink(x);return true;}}}// 查找失败return false;}/*** Returns a list-iterator of the elements in this list (in proper* sequence), starting at the specified position in the list. Obeys the* general contract of {@code List.listIterator(int)}.* <p>* <p>* The list-iterator is <i>fail-fast</i>: if the list is structurally* modified at any time after the Iterator is created, in any way except* through the list-iterator's own {@code remove} or {@code add} methods,* the list-iterator will throw a {@code ConcurrentModificationException}.* Thus, in the face of concurrent modification, the iterator fails quickly* and cleanly, rather than risking arbitrary, non-deterministic behavior at* an undetermined time in the future.* * @param index*            index of the first element to be returned from the*            list-iterator (by a call to {@code next})* @return a ListIterator of the elements in this list (in proper sequence),*         starting at the specified position in the list* @throws IndexOutOfBoundsException*             {@inheritDoc}* @see List#listIterator(int)*/public ListIterator<E> listIterator(int index) {checkPositionIndex(index);return new ListItr(index);}private class ListItr implements ListIterator<E> {private Node<E> lastReturned;private Node<E> next;private int nextIndex;private int expectedModCount = modCount;ListItr(int index) {// assert isPositionIndex(index);next = (index == size) ? null : node(index);nextIndex = index;}public boolean hasNext() {return nextIndex < size;}public E next() {checkForComodification();if (!hasNext())throw new NoSuchElementException();lastReturned = next;next = next.next;nextIndex++;return lastReturned.item;}public boolean hasPrevious() {return nextIndex > 0;}public E previous() {checkForComodification();if (!hasPrevious())throw new NoSuchElementException();lastReturned = next = (next == null) ? last : next.prev;nextIndex--;return lastReturned.item;}public int nextIndex() {return nextIndex;}public int previousIndex() {return nextIndex - 1;}public void remove() {checkForComodification();if (lastReturned == null)throw new IllegalStateException();Node<E> lastNext = lastReturned.next;unlink(lastReturned);if (next == lastReturned)next = lastNext;elsenextIndex--;lastReturned = null;expectedModCount++;}public void set(E e) {if (lastReturned == null)throw new IllegalStateException();checkForComodification();lastReturned.item = e;}public void add(E e) {checkForComodification();lastReturned = null;if (next == null)linkLast(e);elselinkBefore(e, next);nextIndex++;expectedModCount++;}public void forEachRemaining(Consumer<? super E> action) {Objects.requireNonNull(action);while (modCount == expectedModCount && nextIndex < size) {action.accept(next.item);lastReturned = next;next = next.next;nextIndex++;}checkForComodification();}final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}}/*** 节点的数据结构,包含前后节点的引用和当前节点* * @param <E>*/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;}}/*** 返回迭代器* * @since 1.6*/public Iterator<E> descendingIterator() {return new DescendingIterator();}/*** 因为采用链表实现,所以迭代器很简单*/private class DescendingIterator implements Iterator<E> {private final ListItr itr = new ListItr(size());public boolean hasNext() {return itr.hasPrevious();}public E next() {return itr.previous();}public void remove() {itr.remove();}}/*** 父类克隆方法*/@SuppressWarnings("unchecked")private LinkedList<E> superClone() {try {return (LinkedList<E>) super.clone();} catch (CloneNotSupportedException e) {throw new InternalError(e);}}/*** 克隆,浅拷贝* * 浅拷贝时,若存储的是对象的引用,拷贝时,对象本身的改变将表现到副本中,而深拷贝不会。* @return a shallow copy of this {@code LinkedList} instance*/public Object clone() {LinkedList<E> clone = superClone();// 链表初始化clone.first = clone.last = null;clone.size = 0;clone.modCount = 0;// 插入结点for (Node<E> x = first; x != null; x = x.next)clone.add(x.item);// 返回克隆后的对象引用return clone;}/*** 返回新的数组,数组含有列表中所有元素*/public Object[] toArray() {Object[] result = new Object[size];int i = 0;for (Node<E> x = first; x != null; x = x.next)result[i++] = x.item;return result;}/*** Returns an array containing all of the elements in this list in proper* sequence (from first to last element); the runtime type of the returned* array is that of the specified array. If the list fits in the specified* array, it is returned therein. Otherwise, a new array is allocated with* the runtime type of the specified array and the size of this list.* <p>* <p>* If the list fits in the specified array with room to spare (i.e., the* array has more elements than the list), the element in the array* immediately following the end of the list is set to {@code null}. (This* is useful in determining the length of the list <i>only</i> if the* caller knows that the list does not contain any null elements.)* <p>* <p>* Like the {@link #toArray()} method, this method acts as bridge between* array-based and collection-based APIs. Further, this method allows* precise control over the runtime type of the output array, and may, under* certain circumstances, be used to save allocation costs.* <p>* <p>* Suppose {@code x} is a list known to contain only strings. The following* code can be used to dump the list into a newly allocated array of* {@code String}:* <p>* * <pre>*     String[] y = x.toArray(new String[0]);* </pre>* * <p>* Note that {@code toArray(new Object[0])} is identical in function to* {@code toArray()}.* * @param a*            the array into which the elements of the list are to be*            stored, if it is big enough; otherwise, a new array of the*            same runtime type is allocated for this purpose.* @return an array containing the elements of the list* @throws ArrayStoreException*             if the runtime type of the specified array is not a supertype*             of the runtime type of every element in this list* @throws NullPointerException*             if the specified array is null*/@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {if (a.length < size)a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);int i = 0;Object[] result = a;for (Node<E> x = first; x != null; x = x.next)result[i++] = x.item;if (a.length > size)a[size] = null;return a;}private static final long serialVersionUID = 876323262645176354L;/*** 序列化*/private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {// 默认序列化s.defaultWriteObject();// 写入元素数量s.writeInt(size);// 遍历链表,写入所有元素for (Node<E> x = first; x != null; x = x.next)s.writeObject(x.item);}/*** 反序列化*/@SuppressWarnings("unchecked")private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {// 默认反序列化s.defaultReadObject();// 读取元素数量int size = s.readInt();// 遍历链表,读取所有元素并尾部插入for (int i = 0; i < size; i++)linkLast((E) s.readObject());}/*** Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>* and <em>fail-fast</em> {@link Spliterator} over the elements in this* list.* <p>* <p>* The {@code Spliterator} reports {@link Spliterator#SIZED} and* {@link Spliterator#ORDERED}. Overriding implementations should document* the reporting of additional characteristic values.* * @return a {@code Spliterator} over the elements in this list* @implNote The {@code Spliterator} additionally reports*           {@link Spliterator#SUBSIZED} and implements {@code trySplit} to*           permit limited parallelism..* @since 1.8*/@Overridepublic Spliterator<E> spliterator() {return new LLSpliterator<E>(this, -1, 0);}/*** A customized variant of Spliterators.IteratorSpliterator*/static final class LLSpliterator<E> implements Spliterator<E> {static final int BATCH_UNIT = 1 << 10;  // batch array size incrementstatic final int MAX_BATCH = 1 << 25;  // max batch array size;final LinkedList<E> list; // null OK unless traversedNode<E> current;      // current node; null until initializedint est;              // size estimate; -1 until first neededint expectedModCount; // initialized when est setint batch;            // batch size for splitsLLSpliterator(LinkedList<E> list, int est, int expectedModCount) {this.list = list;this.est = est;this.expectedModCount = expectedModCount;}final int getEst() {int s; // force initializationfinal LinkedList<E> lst;if ((s = est) < 0) {if ((lst = list) == null)s = est = 0;else {expectedModCount = lst.modCount;current = lst.first;s = est = lst.size;}}return s;}public long estimateSize() {return (long) getEst();}public Spliterator<E> trySplit() {Node<E> p;int s = getEst();if (s > 1 && (p = current) != null) {int n = batch + BATCH_UNIT;if (n > s)n = s;if (n > MAX_BATCH)n = MAX_BATCH;Object[] a = new Object[n];int j = 0;do {a[j++] = p.item;} while ((p = p.next) != null && j < n);current = p;batch = j;est = s - j;return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);}return null;}public void forEachRemaining(Consumer<? super E> action) {Node<E> p;int n;if (action == null) throw new NullPointerException();if ((n = getEst()) > 0 && (p = current) != null) {current = null;est = 0;do {E e = p.item;p = p.next;action.accept(e);} while (p != null && --n > 0);}if (list.modCount != expectedModCount)throw new ConcurrentModificationException();}public boolean tryAdvance(Consumer<? super E> action) {Node<E> p;if (action == null) throw new NullPointerException();if (getEst() > 0 && (p = current) != null) {--est;E e = p.item;current = p.next;action.accept(e);if (list.modCount != expectedModCount)throw new ConcurrentModificationException();return true;}return false;}public int characteristics() {return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;}}}

java常用类介绍及源码阅读(LinkedList)相关推荐

  1. java常用类介绍及源码阅读(ArrayList)

    java.util  类 ArrayList<E> 继承关系: java.lang.Objectjava.util.AbstractCollection<E>java.util ...

  2. 17 任务调度相关类综述——Live555源码阅读(一)任务调度相关类

    这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...

  3. 16 BasicHashTable基本哈希表类(三)——Live555源码阅读(一)基本组件类

    这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...

  4. java jdk 类加载机制_JDK源码阅读之类加载

    java类加载 类的生命周期(类加载过程) LLIUU+VPR 加载(Loading) 链接(Linking) 验证(Verification) 准备(Preparation) 解析(Resoluti ...

  5. java源码阅读LinkedList

    1类签名与注释 public class LinkedList<E>extends AbstractSequentialList<E>implements List<E& ...

  6. 【java】java 定时任务线程池 ScheduledThreadPoolExecutor 源码阅读

    文章目录 1.概述 1.1 问题 1.2 简介 1.2 数据结构 2.源码解析 2.1 内部类ScheduledFutureTask 2.1.1 compareTo 2.1.2 核心方法run() 2 ...

  7. java spring ioc 实例_Spring 源码阅读(IOC容器)-bean的实例化以及注入

    3.Bean的实例化以及注入过程分析 Bean的实例以及注入是在getBean时触发的,由于外部容器是与外部调用交互的桥梁,我们首先从外部容器入手,AbstractApplicationContext ...

  8. Java常用类全面解析(含部分源码)

    常用类 文章目录 常用类 字符串相关的类 String 类 说明 案例 String 的实例方式 String 中的常用方法 案例一 案例二 案例三 String 类与其它结构之间的转换 小复习-与基 ...

  9. java io中断_JDK源码阅读:InterruptibleChannel 与可中断 IO

    来源:木杉的博客 , imushan.com/2018/08/01/java/language/JDK源码阅读-InterruptibleChannel与可中断IO/ Java传统IO是不支持中断的, ...

最新文章

  1. 【android】java.lang.NoClassDefFoundError或classnotfount等异常错误
  2. elasticsearch _field_stats 源码分析
  3. 1353. 滑雪场设计【难度: 一般 / 知识点: 枚举 贪心】
  4. Calendar Game POJ - 1082(关于日历的博弈问题)
  5. 网关是什么?有什么作用?
  6. jumpserver堡垒机 (资源)
  7. 五笔字型初学者常见问题答疑
  8. java判断胡牌_怎么写一个c++程序判断麻将是否胡牌(只讨论清一色的情况)
  9. 软件测试 | 测试开发 | 双非院校,从外包到外企涨薪85%,他的涨薪秘籍全公开
  10. 基于Hbase和SpringBoot的分布式HOS文件存储系统
  11. 软件设计师知识体系归纳总结
  12. 小米手机系统更新没有数据连接到服务器吗,小米手机无服务怎么解决
  13. 重新编译开源代码绕过杀毒软件(无导入表编译)
  14. 关于二维网格导入autodyn的问题
  15. Java——关于Excle表格的操作
  16. 【即时通信】openfire安装和配置讲解
  17. SEO基础之用户停留时间(用户体验连载2)
  18. 基础-轨道力学的主要研究内容
  19. 精准医学: 尿液DNA甲基化检测有助于膀胱癌早期和复发监测|早期筛查专题
  20. 马云提前转让了5%的滴滴股权,这是巧合还是未卜先知?

热门文章

  1. half-sync/half-async 和 Leader/Followers 模式的主要区别
  2. 漫谈 Linux,Windows 和 Mac
  3. wince6.0编译命令分析
  4. WinCE中命令行工具cvrtbin简介
  5. docker访问宿主机mysql_docker容器内访问宿主机127.0.0.1服务
  6. Linux显示txt文件,如何在Linux中显示文本文件中的某些行?
  7. 【转】UML基础: 第1部分 - 类图 (Class Diagram)
  8. SharePoint学习札记[5] — 设置匿名访问
  9. android打包工具多渠道批量打包,Android 快速渠道批量打包详解教程-美团多渠道打包方案...
  10. 解决Hbase输入list,创建表报错,输入status可以,org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: S