LinkedList源碼分析

/*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/

package java.util;

import java.util.function.Consumer;

/**
* Doubly-linked list implementation of the {@code List} and {@code Deque}
* interfaces.  Implements all optional list operations, and permits all
* elements (including {@code null}).
*
* <p>All of the operations perform as could be expected for a doubly-linked
* list.  Operations that index into the list will traverse the list from
* the beginning or the end, whichever is closer to the specified index.
*
* <p><strong>Note that this implementation is not synchronized.</strong>
* If multiple threads access a linked list concurrently, and at least
* one of the threads modifies the list structurally, it <i>must</i> be
* synchronized externally.  (A structural modification is any operation
* that adds or deletes one or more elements; merely setting the value of
* an element is not a structural modification.)  This is typically
* accomplished by synchronizing on some object that naturally
* encapsulates the list.
*
* If no such object exists, the list should be "wrapped" using the
* {@link Collections#synchronizedList Collections.synchronizedList}
* method.  This is best done at creation time, to prevent accidental
* unsynchronized access to the list:<pre>
*   List list = Collections.synchronizedList(new LinkedList(...));</pre>
*
* <p>The iterators returned by this class's {@code iterator} and
* {@code listIterator} methods are <i>fail-fast</i>: if the list is
* structurally modified at any time after the iterator is created, in
* any way except through the Iterator's own {@code remove} or
* {@code add} methods, the iterator will throw a {@link
* 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.
*
* <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
* as it is, generally speaking, impossible to make any hard guarantees in the
* presence of unsynchronized concurrent modification.  Fail-fast iterators
* throw {@code ConcurrentModificationException} on a best-effort basis.
* Therefore, it would be wrong to write a program that depended on this
* exception for its correctness:   <i>the fail-fast behavior of iterators
* should be used only to detect bugs.</i>
*
* <p>This class is a member of the
* <a href="{@docRoot}/../technotes/guides/collections/index.html">
* Java Collections Framework</a>.
*
* @author  Josh Bloch
* @see     List
* @see     ArrayList
* @since 1.2
* @param <E> the type of elements held in this collection
*/

public class LinkedList<E>
   extends AbstractSequentialList<E>
   implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
   // 集合中元素的數(shù)量
   transient int size = 0;

   /**
    * Pointer to first node.
    * Invariant: (first == null && last == null) ||
    *            (first.prev == null && first.item != null)
    */
   // 鏈表的頭結(jié)點(diǎn)
   transient Node<E> first;

   /**
    * Pointer to last node.
    * Invariant: (first == null && last == null) ||
    *            (last.next == null && last.item != null)
    */
   // 鏈表的尾節(jié)點(diǎn)
   transient Node<E> last;

   /**
    * Constructs an empty list.
    */
   // 無(wú)參構(gòu)造方法
   public LinkedList() {
   }

   /**
    * Constructs a list containing the elements of the specified
    * collection, in the order they are returned by the collection's
    * iterator.
    *
    * @param  c the collection whose elements are to be placed into this list
    * @throws NullPointerException if the specified collection is null
    */
   // 指定集合作為參數(shù)的構(gòu)造方法
   public LinkedList(Collection<? extends E> c) {
       this();
       addAll(c);
   }

   /**
    * Links e as first element.
    */
   private void linkFirst(E e) {
       //f 指向鏈表頭結(jié)點(diǎn)
       final Node<E> f = first;
       // 創(chuàng)建一個(gè)新節(jié)點(diǎn)
       final Node<E> newNode = new Node<>(null, e, f);
       // first 指向新節(jié)點(diǎn)
       first = newNode;
       // 如果f為null 表明之前鏈表為空 則插入后 last指向新結(jié)點(diǎn)
       if (f == null)
           last = newNode;
       // 鏈表之前不為空則f.prev指向新節(jié)點(diǎn)
       else
           f.prev = newNode;
       // 元素?cái)?shù)量+1
       size++;
       modCount++;
   }

   /**
    * Links e as last element.
    */
   void linkLast(E e) {
       // l指向尾節(jié)點(diǎn)
       final Node<E> l = last;
       // 創(chuàng)建一個(gè)新的節(jié)點(diǎn)
       final Node<E> newNode = new Node<>(l, e, null);
       //last指向新節(jié)點(diǎn)
       last = newNode;
       // 如果l為null 表明插入之前鏈表為null 則插入后first指向新及誒單
       if (l == null)
           first = newNode;
       // 鏈表之前不為空 則l.next指向新節(jié)點(diǎn)
       else
           l.next = newNode;
       size++;
       modCount++;
   }

   /**
    * Inserts element e before non-null Node succ.
    */
   // 在某個(gè)節(jié)點(diǎn)前面插入新的節(jié)點(diǎn)
   void linkBefore(E e, Node<E> succ) {
       // assert succ != null;
       final Node<E> pred = succ.prev;
       final Node<E> newNode = new Node<>(pred, e, succ);
       succ.prev = newNode;
       if (pred == null)
           first = newNode;
       else
           pred.next = newNode;
       size++;
       modCount++;
   }

   /**
    * Unlinks non-null first node f.
    */
   private E unlinkFirst(Node<E> f) {
       // assert f == first && f != null;
       // element保存頭節(jié)點(diǎn)的值
       final E element = f.item;
       // next指向下一個(gè)節(jié)點(diǎn)
       final Node<E> next = f.next;
       // 頭結(jié)點(diǎn)的item和next置空 方便GC回收
       f.item = null;
       f.next = null; // help GC
       // 頭結(jié)點(diǎn)指向next節(jié)點(diǎn)
       first = next;
       // 如果next節(jié)點(diǎn)為null 則表示鏈表為空 last指向null
       if (next == null)
           last = null;
       // 否則next節(jié)點(diǎn)作為頭結(jié)點(diǎn) 頭結(jié)點(diǎn)的pre指向null
       else
           next.prev = null;
       // 數(shù)量-1
       size--;
       modCount++;
       // 返回舊頭結(jié)點(diǎn)保存的值
       return element;
   }

   /**
    * Unlinks non-null last node l.
    */
   private E unlinkLast(Node<E> l) {
       // assert l == last && l != null;
       // elment保存尾節(jié)點(diǎn)的值
       final E element = l.item;
       //prev保存倒數(shù)第二個(gè)節(jié)點(diǎn)
       final Node<E> prev = l.prev;
       // 置空方便GC回收
       l.item = null;
       l.prev = null; // help GC
       // last指向倒數(shù)第二個(gè)節(jié)點(diǎn)
       last = prev;
       if (prev == null)
           first = null;
       // 尾節(jié)點(diǎn)的next指向null
       else
           prev.next = null;
       size--;
       modCount++;
       // 返回移除的尾節(jié)點(diǎn)保存的值
       return element;
   }

   /**
    * Unlinks non-null node x.
    */
   E unlink(Node<E> x) {
       // assert x != null;
       // element指向要?jiǎng)h除節(jié)點(diǎn)保存的元素
       final E element = x.item;
       // next指向被刪節(jié)點(diǎn)的后置節(jié)點(diǎn)
       final Node<E> next = x.next;
       // prev指向被刪節(jié)點(diǎn)的前置節(jié)點(diǎn)
       final Node<E> prev = x.prev;
       // prev為null 表示被刪節(jié)點(diǎn)為頭結(jié)點(diǎn) 則first指向第二個(gè)節(jié)點(diǎn)
       if (prev == null) {
           first = next;
       } else {
           // 否則刪除的是鏈表中其他節(jié)點(diǎn)
           prev.next = next;
           // 被刪節(jié)點(diǎn) 前置置空 方便GC回收
           x.prev = null;
       }
       // next 為null表示被刪節(jié)點(diǎn)為尾節(jié)點(diǎn)則last指向倒數(shù)第二個(gè)節(jié)點(diǎn)
       if (next == null) {
           last = prev;
       } else {
           next.prev = prev;
           // 被刪節(jié)點(diǎn) 后置置空 方便回收
           x.next = null;
       }
       // 被刪節(jié)點(diǎn) item置空 方便GC回收
       x.item = null;
       size--;
       modCount++;
       return element;
   }

   /**
    * Returns the first element in this list.
    *
    * @return the first element in this list
    * @throws NoSuchElementException if this list is empty
    */
   // 獲取鏈表頭結(jié)點(diǎn)保存的元素 如果頭結(jié)點(diǎn)為null 拋出NoSuchElementException異常
   public E getFirst() {
       final Node<E> f = first;
       if (f == null)
           throw new NoSuchElementException();
       return f.item;
   }

   /**
    * Returns the last element in this list.
    *
    * @return the last element in this list
    * @throws NoSuchElementException if this list is empty
    */
   // 獲取鏈表尾結(jié)點(diǎn)保存的元素 如果尾結(jié)點(diǎn)為null 拋出NoSuchElementException異常
   public E getLast() {
       final Node<E> l = last;
       if (l == null)
           throw new NoSuchElementException();
       return l.item;
   }

   /**
    * Removes and returns the first element from this list.
    *
    * @return the first element from this list
    * @throws NoSuchElementException if this list is empty
    */
   // 移除頭結(jié)點(diǎn) 并返回該節(jié)點(diǎn)保存的元素 頭結(jié)點(diǎn)為null 拋出NoSuchElementException異常
   public E removeFirst() {
       final Node<E> f = first;
       if (f == null)
           throw new NoSuchElementException();
       return unlinkFirst(f);
   }

   /**
    * Removes and returns the last element from this list.
    *
    * @return the last element from this list
    * @throws NoSuchElementException if this list is empty
    */
   // 移除尾節(jié)點(diǎn) 如果尾節(jié)點(diǎn)為null 拋出NoSuchElementException異常
   public E removeLast() {
       final Node<E> l = last;
       if (l == null)
           throw new NoSuchElementException();
       return unlinkLast(l);
   }

   /**
    * Inserts the specified element at the beginning of this list.
    *
    * @param e the element to add
    */
   // 在鏈表頭部添加一個(gè)節(jié)點(diǎn)
   public void addFirst(E e) {
       linkFirst(e);
   }

   /**
    * Appends the specified element to the end of this list.
    *
    * <p>This method is equivalent to {@link #add}.
    *
    * @param e the element to add
    */
   // 在鏈表尾部添加一個(gè)節(jié)點(diǎn)
   public void addLast(E e) {
       linkLast(e);
   }

   /**
    * Returns {@code true} if this list contains the specified element.
    * More formally, returns {@code true} if and only if this list contains
    * at least one element {@code e} such that
    * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
    *
    * @param o element whose presence in this list is to be tested
    * @return {@code true} if this list contains the specified element
    */
   // 判斷鏈表是否包含指定的元素
   public boolean contains(Object o) {
       return indexOf(o) != -1;
   }

   /**
    * Returns the number of elements in this list.
    *
    * @return the number of elements in this list
    */
   // 返回鏈表中保存的元素的數(shù)量
   public int size() {
       return size;
   }

   /**
    * Appends the specified element to the end of this list.
    *
    * <p>This method is equivalent to {@link #addLast}.
    *
    * @param e element to be appended to this list
    * @return {@code true} (as specified by {@link Collection#add})
    */
   // 往鏈表中添加新的元素
   public boolean add(E e) {
       linkLast(e);
       return true;
   }

   /**
    * Removes the first occurrence of the specified element from this list,
    * if it is present.  If this list does not contain the element, it is
    * unchanged.  More formally, removes the element with the lowest index
    * {@code i} such that
    * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
    * (if such an element exists).  Returns {@code true} if this list
    * contained the specified element (or equivalently, if this list
    * changed as a result of the call).
    *
    * @param o element to be removed from this list, if present
    * @return {@code true} if this list contained the specified element
    */
   // 刪除鏈表中指定的元素 如果不存在則返回false  刪除成功返回true
   public boolean remove(Object o) {
       // null與非null對(duì)象分別處理 
       if (o == null) {
           for (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;
   }

   /**
    * Appends all of the elements in the specified collection to the end of
    * this list, in the order that they are returned by the specified
    * collection's iterator.  The behavior of this operation is undefined if
    * the specified collection is modified while the operation is in
    * progress.  (Note that this will occur if the specified collection is
    * this list, and it's nonempty.)
    *
    * @param c collection containing elements to be added to this list
    * @return {@code true} if this list changed as a result of the call
    * @throws NullPointerException if the specified collection is null
    */
   // 添加一個(gè)集合的元素到當(dāng)前的鏈表中
   public boolean addAll(Collection<? extends E> c) {
       return addAll(size, c);
   }

   /**
    * Inserts all of the elements in the specified collection into this
    * list, starting at the specified position.  Shifts the element
    * currently at that position (if any) and any subsequent elements to
    * the right (increases their indices).  The new elements will appear
    * in the list in the order that they are returned by the
    * specified collection's iterator.
    *
    * @param index index at which to insert the first element
    *              from the specified collection
    * @param c collection containing elements to be added to this list
    * @return {@code true} if this list changed as a result of the call
    * @throws IndexOutOfBoundsException {@inheritDoc}
    * @throws NullPointerException if the specified collection is null
    */
   // 在指定的下標(biāo)處插入集合
   public boolean addAll(int index, Collection<? extends E> c) {
       checkPositionIndex(index);
       // 集合c轉(zhuǎn)為Object數(shù)組
       Object[] a = c.toArray();
       // 數(shù)組a的長(zhǎng)度
       int numNew = a.length;
       // 如果要插入的集合為空 則直接返回false
       if (numNew == 0)
           return false;
       
       Node<E> pred, succ;
       // 要插入的位置是鏈表的尾部 succ指向null  pred指向當(dāng)前的尾節(jié)點(diǎn)
       if (index == size) {
           succ = null;
           pred = last;
       } else {
           succ = node(index);
           // succ的前置節(jié)點(diǎn)指向pred
           pred = succ.prev;
       }

       for (Object o : a) {
           @SuppressWarnings("unchecked") E e = (E) o;
           Node<E> newNode = new Node<>(pred, e, null);
           if (pred == null)
               first = newNode;
           // pred部位null表示在鏈表末尾插入
           else
               pred.next = newNode;
           pred = newNode;
       }

       if (succ == null) {
           last = pred;
       } else {
           pred.next = succ;
           succ.prev = pred;
       }

       size += numNew;
       modCount++;
       return true;
   }

   /**
    * Removes all of the elements from this list.
    * The list will be empty after this call returns.
    */
   // 清空鏈表中的所有元素
   public void clear() {
       // Clearing all of the links between nodes is "unnecessary", but:
       // - helps a generational GC if the discarded nodes inhabit
       //   more than one generation
       // - is sure to free memory even if there is a reachable Iterator
       // 遍歷鏈表 將所有引用都置空 方便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;
       size = 0;
       modCount++;
   }


   // Positional Access Operations

   /**
    * Returns the element at the specified position in this list.
    *
    * @param index index of the element to return
    * @return the element at the specified position in this list
    * @throws IndexOutOfBoundsException {@inheritDoc}
    */
   // 獲取指定下標(biāo)處的元素 如果越界 拋出IndexOutOfBoundsException異常
   public E get(int index) {
       checkElementIndex(index);
       return node(index).item;
   }

   /**
    * Replaces the element at the specified position in this list with the
    * specified element.
    *
    * @param index index of the element to replace
    * @param element element to be stored at the specified position
    * @return the element previously at the specified position
    * @throws IndexOutOfBoundsException {@inheritDoc}
    */
   //替換掉index位置的值 返回舊值
   public E set(int index, E element) {
       checkElementIndex(index);
       Node<E> x = node(index);
       E oldVal = x.item;
       x.item = element;
       return oldVal;
   }

   /**
    * Inserts the specified element at the specified position in this list.
    * Shifts the element currently at that position (if any) and any
    * subsequent elements to the right (adds one to their indices).
    *
    * @param index index at which the specified element is to be inserted
    * @param element element to be inserted
    * @throws IndexOutOfBoundsException {@inheritDoc}
    */
   // 在index處插入新的節(jié)點(diǎn)
   public void add(int index, E element) {
       checkPositionIndex(index);
       // 如果插入的位置是末尾 直接在末尾添加節(jié)點(diǎn)即可
       if (index == size)
           linkLast(element);
       else
           linkBefore(element, node(index));
   }

   /**
    * Removes the element at the specified position in this list.  Shifts any
    * subsequent elements to the left (subtracts one from their indices).
    * Returns the element that was removed from the list.
    *
    * @param index the index of the element to be removed
    * @return the element previously at the specified position
    * @throws IndexOutOfBoundsException {@inheritDoc}
    */
   // 刪除index處節(jié)點(diǎn)
   public E remove(int index) {
       checkElementIndex(index);
       return unlink(node(index));
   }

   /**
    * Tells if the argument is the index of an existing element.
    */
   // 校驗(yàn)下標(biāo)是否正常[0,size) 適用于查找
   private boolean isElementIndex(int index) {
       return index >= 0 && index < size;
   }

   /**
    * Tells if the argument is the index of a valid position for an
    * iterator or an add operation.
    */
   // 校驗(yàn)下標(biāo)是否是正常[0,size] 適用于插入
   private boolean isPositionIndex(int index) {
       return index >= 0 && index <= size;
   }

   /**
    * Constructs an IndexOutOfBoundsException detail message.
    * Of the many possible refactorings of the error handling code,
    * this "outlining" performs best with both server and client VMs.
    */
   private String outOfBoundsMsg(int index) {
       return "Index: "+index+", Size: "+size;
   }
   // 下標(biāo)越界 拋出IndexOutOfBoundsException異常
   private void checkElementIndex(int index) {
       if (!isElementIndex(index))
           throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
   }
   // 下標(biāo)越界 拋出IndexOutOfBoundsException異常
   private void checkPositionIndex(int index) {
       if (!isPositionIndex(index))
           throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
   }

   /**
    * Returns the (non-null) Node at the specified element index.
    */
   Node<E> node(int index) {
       // assert isElementIndex(index);
       // 判斷index的位置 在鏈表左側(cè)還是鏈表右側(cè) 然后決定是從左側(cè)遍歷還是從右側(cè)遍歷
       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;
       }
   }

   // Search Operations

   /**
    * Returns the index of the first occurrence of the specified element
    * in this list, or -1 if this list does not contain the element.
    * More formally, returns the lowest index {@code i} such that
    * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
    * or -1 if there is no such index.
    *
    * @param o element to search for
    * @return the index of the first occurrence of the specified element in
    *         this list, or -1 if this list does not contain the element
    */
   // 查找指定的元素對(duì)應(yīng)的下標(biāo) 返回第一個(gè)出現(xiàn)位置的下標(biāo) 如果不存在則返回-1
   public int indexOf(Object o) {
       int index = 0;
       // 如果要查找的對(duì)象為null 則查找是否存儲(chǔ)了null節(jié)點(diǎn)
       if (o == null) {
           // 從頭結(jié)點(diǎn)開(kāi)始遍歷查找 因此該方法的時(shí)間復(fù)雜度為O(n)
           for (Node<E> x = first; x != null; x = x.next) {
               if (x.item == null)
                   return index;
               index++;
           }
       } else {
           // 非null的對(duì)象 也是遍歷鏈表查找 通過(guò)equals方法進(jìn)行比較
           for (Node<E> x = first; x != null; x = x.next) {
               if (o.equals(x.item))
                   return index;
               index++;
           }
       }
       return -1;
   }

   /**
    * Returns the index of the last occurrence of the specified element
    * in this list, or -1 if this list does not contain the element.
    * More formally, returns the highest index {@code i} such that
    * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
    * or -1 if there is no such index.
    *
    * @param o element to search for
    * @return the index of the last occurrence of the specified element in
    *         this list, or -1 if this list does not contain the element
    */
   // 查找指定元素對(duì)應(yīng)的下標(biāo) 返回最后出現(xiàn)的位置下標(biāo) 如果不存在返回-1
   public int lastIndexOf(Object o) {
       // index從size開(kāi)始遞減
       int index = size;
       // 從鏈表尾部開(kāi)始往前遍歷
       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;
   }

   // Queue operations.

   /**
    * Retrieves, but does not remove, the head (first element) of this list.
    *
    * @return the head of this list, or {@code null} if this list is empty
    * @since 1.5
    */
   // 獲取鏈表首部節(jié)點(diǎn) 不移除首部節(jié)點(diǎn) 如果鏈表為空返回null
   public E peek() {
       final Node<E> f = first;
       return (f == null) ? null : f.item;
   }

   /**
    * Retrieves, but does not remove, the head (first element) of this list.
    *
    * @return the head of this list
    * @throws NoSuchElementException if this list is empty
    * @since 1.5
    */
   // 獲取首部節(jié)點(diǎn) 不移除該節(jié)點(diǎn) 如果鏈表為空 則拋出NoSuchElementException異常
   public E element() {
       return getFirst();
   }

   /**
    * Retrieves and removes the head (first element) of this list.
    *
    * @return the head of this list, or {@code null} if this list is empty
    * @since 1.5
    */
   // 獲取首部節(jié)點(diǎn) 并且移除該節(jié)點(diǎn)  如果鏈表為空 則返回null
   public E poll() {
       final Node<E> f = first;
       return (f == null) ? null : unlinkFirst(f);
   }

   /**
    * Retrieves and removes the head (first element) of this list.
    *
    * @return the head of this list
    * @throws NoSuchElementException if this list is empty
    * @since 1.5
    */
   //移除首部節(jié)點(diǎn) 并返回該節(jié)點(diǎn) 如果鏈表為空則拋出NoSuchElementException異常
   public E remove() {
       return removeFirst();
   }

   /**
    * Adds the specified element as the tail (last element) of this list.
    *
    * @param e the element to add
    * @return {@code true} (as specified by {@link Queue#offer})
    * @since 1.5
    */
   //在鏈表末尾添加新的節(jié)點(diǎn)
   public boolean offer(E e) {
       return add(e);
   }

   // Deque operations
   /**
    * Inserts the specified element at the front of this list.
    *
    * @param e the element to insert
    * @return {@code true} (as specified by {@link Deque#offerFirst})
    * @since 1.6
    */
   // 在鏈表的首部插入新的節(jié)點(diǎn)
   public boolean offerFirst(E e) {
       addFirst(e);
       return true;
   }

   /**
    * Inserts the specified element at the end of this list.
    *
    * @param e the element to insert
    * @return {@code true} (as specified by {@link Deque#offerLast})
    * @since 1.6
    */
   // 在鏈表的末尾添加新的節(jié)點(diǎn)
   public boolean offerLast(E e) {
       addLast(e);
       return true;
   }

   /**
    * Retrieves, but does not remove, the first element of this list,
    * or returns {@code null} if this list is empty.
    *
    * @return the first element of this list, or {@code null}
    *         if this list is empty
    * @since 1.6
    */
   // 等同于peek方法
   public E peekFirst() {
       final Node<E> f = first;
       return (f == null) ? null : f.item;
    }

   /**
    * Retrieves, but does not remove, the last element of this list,
    * or returns {@code null} if this list is empty.
    *
    * @return the last element of this list, or {@code null}
    *         if this list is empty
    * @since 1.6
    */
   public E peekLast() {
       final Node<E> l = last;
       return (l == null) ? null : l.item;
   }

   /**
    * Retrieves and removes the first element of this list,
    * or returns {@code null} if this list is empty.
    *
    * @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;
       return (f == null) ? null : unlinkFirst(f);
   }

   /**
    * Retrieves and removes the last element of this list,
    * or returns {@code null} if this list is empty.
    *
    * @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;
       return (l == null) ? null : unlinkLast(l);
   }

   /**
    * Pushes an element onto the stack represented by this list.  In other
    * words, inserts the element at the front of this list.
    *
    * <p>This method is equivalent to {@link #addFirst}.
    *
    * @param e the element to push
    * @since 1.6
    */
   // 進(jìn)棧 在鏈表首部添加新的節(jié)點(diǎn)
   public void push(E e) {
       addFirst(e);
   }

   /**
    * Pops an element from the stack represented by this list.  In other
    * words, removes and returns the first element of this list.
    *
    * <p>This method is equivalent to {@link #removeFirst()}.
    *
    * @return the element at the front of this list (which is the top
    *         of the stack represented by this list)
    * @throws NoSuchElementException if this list is empty
    * @since 1.6
    */
   // 出棧 從鏈表首部刪除節(jié)點(diǎn) 如果鏈表(棧)為空 則拋出NoSuchElementException異常
   public E pop() {
       return removeFirst();
   }

   /**
    * Removes the first occurrence of the specified element in this
    * list (when traversing the list from head to tail).  If the list
    * does not contain the element, it is unchanged.
    *
    * @param o element to be removed from this list, if present
    * @return {@code true} if the list contained the specified element
    * @since 1.6
    */
   public boolean removeFirstOccurrence(Object o) {
       return remove(o);
   }

   /**
    * Removes the last occurrence of the specified element in this
    * list (when traversing the list from head to tail).  If the list
    * does not contain the element, it is unchanged.
    *
    * @param o element to be removed from this list, if present
    * @return {@code true} if the list contained the specified element
    * @since 1.6
    */
   public boolean removeLastOccurrence(Object o) {
       if (o == null) {
           for (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>
    *
    * 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;
           else
               nextIndex--;
           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);
           else
               linkBefore(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();
       }
   }

   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();
   }

   /**
    * Adapter to provide descending iterators via ListItr.previous
    */
   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);
       }
   }

   /**
    * Returns a shallow copy of this {@code LinkedList}. (The elements
    * themselves are not cloned.)
    *
    * @return a shallow copy of this {@code LinkedList} instance
    */
   public Object clone() {
       LinkedList<E> clone = superClone();

       // Put clone into "virgin" state
       clone.first = clone.last = null;
       clone.size = 0;
       clone.modCount = 0;

       // Initialize clone with our elements
       for (Node<E> x = first; x != null; x = x.next)
           clone.add(x.item);

       return clone;
   }

   /**
    * Returns an array containing all of the elements in this list
    * in proper sequence (from first to last element).
    *
    * <p>The returned array will be "safe" in that no references to it are
    * maintained by this list.  (In other words, this method must allocate
    * a new array).  The caller is thus free to modify the returned array.
    *
    * <p>This method acts as bridge between array-based and collection-based
    * APIs.
    *
    * @return an array containing all of the elements in this list
    *         in proper sequence
    */
   // 將鏈表轉(zhuǎn)為數(shù)組
   public Object[] toArray() {
       Object[] result = new Object[size];
       int i = 0;
       // 循環(huán) 放入數(shù)組中
       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>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>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>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}:
    *
    * <pre>
    *     String[] y = x.toArray(new String[0]);</pre>
    *
    * 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;

   /**
    * Saves the state of this {@code LinkedList} instance to a stream
    * (that is, serializes it).
    *
    * @serialData The size of the list (the number of elements it
    *             contains) is emitted (int), followed by all of its
    *             elements (each an Object) in the proper order.
    */
   private void writeObject(java.io.ObjectOutputStream s)
       throws java.io.IOException {
       // Write out any hidden serialization magic
       s.defaultWriteObject();

       // Write out size
       s.writeInt(size);

       // Write out all elements in the proper order.
       for (Node<E> x = first; x != null; x = x.next)
           s.writeObject(x.item);
   }

   /**
    * Reconstitutes this {@code LinkedList} instance from a stream
    * (that is, deserializes it).
    */
   @SuppressWarnings("unchecked")
   private void readObject(java.io.ObjectInputStream s)
       throws java.io.IOException, ClassNotFoundException {
       // Read in any hidden serialization magic
       s.defaultReadObject();

       // Read in size
       int size = s.readInt();

       // Read in all elements in the proper order.
       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>The {@code Spliterator} reports {@link Spliterator#SIZED} and
    * {@link Spliterator#ORDERED}.  Overriding implementations should document
    * the reporting of additional characteristic values.
    *
    * @implNote
    * The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}
    * and implements {@code trySplit} to permit limited parallelism..
    *
    * @return a {@code Spliterator} over the elements in this list
    * @since 1.8
    */
   @Override
   public 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 increment
       static final int MAX_BATCH = 1 << 25;  // max batch array size;
       final LinkedList<E> list; // null OK unless traversed
       Node<E> current;      // current node; null until initialized
       int est;              // size estimate; -1 until first needed
       int expectedModCount; // initialized when est set
       int batch;            // batch size for splits

       LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
           this.list = list;
           this.est = est;
           this.expectedModCount = expectedModCount;
       }

       final int getEst() {
           int s; // force initialization
           final 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;
       }
   }

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阻星,一起剝皮案震驚了整個(gè)濱河市预鬓,隨后出現(xiàn)的幾起案子加矛,更是在濱河造成了極大的恐慌柑营,老刑警劉巖涮帘,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顶瞳,死亡現(xiàn)場(chǎng)離奇詭異独令,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)社付,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)承疲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鸥咖,你說(shuō)我怎么就攤上這事燕鸽。” “怎么了啼辣?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵绵咱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我熙兔,道長(zhǎng),這世上最難降的妖魔是什么艾恼? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任住涉,我火速辦了婚禮,結(jié)果婚禮上钠绍,老公的妹妹穿的比我還像新娘舆声。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布媳握。 她就那樣靜靜地躺著碱屁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蛾找。 梳的紋絲不亂的頭發(fā)上娩脾,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音打毛,去河邊找鬼柿赊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛幻枉,可吹牛的內(nèi)容都是我干的碰声。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼熬甫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼胰挑!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起椿肩,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤瞻颂,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后覆旱,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體蘸朋,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年扣唱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了藕坯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡噪沙,死狀恐怖炼彪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情正歼,我是刑警寧澤辐马,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站局义,受9級(jí)特大地震影響喜爷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜萄唇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一檩帐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧另萤,春花似錦湃密、人聲如沸诅挑。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拔妥。三九已至,卻和暖如春达箍,著一層夾襖步出監(jiān)牢的瞬間没龙,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工幻梯, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兜畸,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓碘梢,卻偏偏與公主長(zhǎng)得像咬摇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子煞躬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348