zoukankan      html  css  js  c++  java
  • LinkedList源码解析(JDK1.8)

       1 package java.util;
       2 
       3 import java.util.function.Consumer;
       4 
       5 /**
       6  * LinkedList是List和Deque接口的双向链表的实现。实现了所有可选List操作,并允许包括null值。
       7  * LinkedList既然是通过双向链表去实现的,那么它可以被当作堆栈、队列或双端队列进行操作。并且其顺序访问非常高效,而随机访问效率比较低。
       8  * 内部方法,注释会描述为节点的操作(如删除第一个节点),公开的方法会描述为元素的操作(如删除第一个元素)
       9  * 注意,此实现不是同步的。 如果多个线程同时访问一个LinkedList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。
      10  * LinkedList不是线程安全的,如果在多线程中使用(修改),需要在外部作同步处理。
      11  * 这通常是通过同步那些用来封装列表的对象来实现的。
      12  * 但如果没有这样的对象存在,则该列表需要运用{@link Collections#synchronizedList Collections.synchronizedList}来进行“包装”,该方法最好是在创建列表对象时完成,为了避免对列表进行突发的非同步操作。
      13  */
      14 
      15 public class LinkedList<E>
      16         extends AbstractSequentialList<E>
      17         implements List<E>, Deque<E>, Cloneable, java.io.Serializable {
      18     /**
      19      * 元素数量
      20      */
      21     transient int size = 0;
      22 
      23     /**
      24      * 首结点引用
      25      */
      26     transient Node<E> first;
      27 
      28     /**
      29      * 尾节点引用
      30      */
      31     transient Node<E> last;
      32 
      33     /**
      34      * 无参构造方法
      35      */
      36     public LinkedList() {
      37     }
      38 
      39     /**
      40      * 通过一个集合初始化LinkedList,元素顺序有这个集合的迭代器返回顺序决定
      41      *
      42      * @param c 其元素将被放入此列表中的集合
      43      * @throws NullPointerException 如果指定的集合是空的
      44      */
      45     public LinkedList(Collection<? extends E> c) {
      46         // 调用无参构造函数
      47         this();
      48         // 添加集合中所有的元素
      49         addAll(c);
      50     }
      51 
      52     /**
      53      * 头插入,即将节点值为e的节点设置为链表首节点,内部使用
      54      */
      55     private void linkFirst(E e) {
      56         //获取当前首结点引用
      57         final Node<E> f = first;
      58         //构建一个prev值为null,节点值为e,next值为f的新节点newNode
      59         final Node<E> newNode = new Node<>(null, e, f);
      60         //将newNode作为首节点
      61         first = newNode;
      62         //如果原首节点为null,即原链表为null,则链表尾节点也设置为newNode
      63         if (f == null)
      64             last = newNode;
      65         else                //否则,原首节点的prev设置为newNode
      66             f.prev = newNode;
      67         size++;             //长度+1
      68         modCount++;         //修改次数+1
      69     }
      70 
      71     /**
      72      * 尾插入,即将节点值为e的节点设置为链表的尾节点
      73      */
      74     void linkLast(E e) {
      75         // 获取当前尾结点引用
      76         final Node<E> l = last;
      77         //构建一个prev值为l,节点值为e,next值为null的新节点newNode
      78         final Node<E> newNode = new Node<>(l, e, null);
      79         //将newNode作为尾节点
      80         last = newNode;
      81         //如果原尾节点为null,即原链表为null,则链表首节点也设置为newNode
      82         if (l == null)
      83             first = newNode;
      84         else    //否则,原尾节点的next设置为newNode
      85             l.next = newNode;
      86         size++;
      87         modCount++;
      88     }
      89 
      90     /**
      91      * 中间插入,在非空节点succ之前插入节点值e
      92      */
      93     void linkBefore(E e, Node<E> succ) {
      94         // assert succ != null;
      95         final Node<E> pred = succ.prev;
      96         //构建一个prev值为succ.prev,节点值为e,next值为succ的新节点newNode
      97         final Node<E> newNode = new Node<>(pred, e, succ);
      98         //设置newNode为succ的前节点
      99         succ.prev = newNode;
     100         //如果succ.prev为null,即如果succ为首节点,则将newNode设置为首节点
     101         if (pred == null)
     102             first = newNode;
     103         else        //如果succ不是首节点
     104             pred.next = newNode;
     105         size++;
     106         modCount++;
     107     }
     108 
     109     /**
     110      * 删除首结点,返回存储的元素,内部使用
     111      */
     112     private E unlinkFirst(Node<E> f) {
     113         // 获取首结点存储的元素
     114         final E element = f.item;
     115         // 获取首结点的后继结点
     116         final Node<E> next = f.next;
     117         // 删除首结点
     118         f.item = null;
     119         f.next = null; //便于垃圾回收期清理
     120         // 原来首结点的后继结点设为首结点
     121         first = next;
     122         // 如果原来首结点的后继结点为空,则尾结点设为null
     123         // 否则,原来首结点的后继结点的前驱结点设为null
     124         if (next == null)
     125             last = null;
     126         else
     127             next.prev = null;
     128         size--;
     129         modCount++;
     130         // 返回原来首结点存储的元素
     131         return element;
     132     }
     133 
     134     /**
     135      * 删除尾结点,返回存储的元素,内部使用
     136      */
     137     private E unlinkLast(Node<E> l) {
     138         // 获取尾结点存储的元素
     139         final E element = l.item;
     140         // 获取尾结点的前驱结点
     141         final Node<E> prev = l.prev;
     142         // 删除尾结点
     143         l.item = null;
     144         l.prev = null; // help GC
     145         // 原来尾结点的前驱结点设为尾结点
     146         last = prev;
     147         // 如果原来尾结点的前驱结点为空,则首结点设为null
     148         // 否则,原来尾结点的前驱结点的后继结点设为null
     149         if (prev == null)
     150             first = null;
     151         else
     152             prev.next = null;
     153         size--;
     154         modCount++;
     155         // 返回原来尾结点存储的元素
     156         return element;
     157     }
     158 
     159     /**
     160      * 删除指定非空结点,返回存储的元素
     161      */
     162     E unlink(Node<E> x) {
     163         // 获取指定非空结点存储的元素
     164         final E element = x.item;
     165         // 获取指定非空结点的后继结点
     166         final Node<E> next = x.next;
     167         // 获取指定非空结点的前驱结点
     168         final Node<E> prev = x.prev;
     169 
     170         /**
     171          * 如果指定非空结点的前驱结点为空,则指定非空结点的后继结点设为首结点
     172          * 否则,指定非空结点的后继结点设为指定非空结点的前驱结点的后继结点,
     173          * 指定非空结点的前驱结点设为null
     174          */
     175         if (prev == null) {
     176             first = next;
     177         } else {
     178             prev.next = next;
     179             x.prev = null;
     180         }
     181 
     182         /**
     183          * 如果指定非空结点的后继结点为空,则指定非空结点的前驱结点设为尾结点
     184          * 否则,指定非空结点的前驱结点设为指定非空结点的后继结点的前驱结点,
     185          * 指定非空结点的后继结点设为null
     186          */
     187         if (next == null) {
     188             last = prev;
     189         } else {
     190             next.prev = prev;
     191             x.next = null;
     192         }
     193 
     194         // 指定非空结点存储的元素设为null
     195         x.item = null;
     196         size--;
     197         modCount++;
     198         // 返回指定非空结点存储的元素
     199         return element;
     200     }
     201 
     202     /**
     203      * 获取首结点存储的元素
     204      *
     205      * @return 首结点存储的元素
     206      * @throws NoSuchElementException 如果链表为空
     207      */
     208     public E getFirst() {
     209         // 获取首结点引用
     210         final Node<E> f = first;
     211         // 如果首结点为空,则抛出无该元素异常
     212         if (f == null)
     213             throw new NoSuchElementException();
     214         // 返回首结点存储的元素
     215         return f.item;
     216     }
     217 
     218     /**
     219      * 获取尾结点存储的元素
     220      *
     221      * @return 尾结点存储的元素
     222      * @throws NoSuchElementException 如果链表为空
     223      */
     224     public E getLast() {
     225         // 获取尾结点引用
     226         final Node<E> l = last;
     227         // 如果尾结点为空,则抛出无该元素异常
     228         if (l == null)
     229             throw new NoSuchElementException();
     230         // 返回尾结点存储的元素
     231         return l.item;
     232     }
     233 
     234     /**
     235      * 删除首结点,返回存储的元素
     236      *
     237      * @return 首结点存储的元素
     238      * @throws NoSuchElementException 如果链表为空
     239      */
     240     public E removeFirst() {
     241         // 获取首结点引用
     242         final Node<E> f = first;
     243         // 如果首结点为空,则抛出无该元素异常
     244         if (f == null)
     245             throw new NoSuchElementException();
     246         // 删除首结点,返回存储的元素
     247         return unlinkFirst(f);
     248     }
     249 
     250     /**
     251      * 删除尾结点,返回存储的元素
     252      *
     253      * @return 尾结点存储的元素
     254      * @throws NoSuchElementException 如果链表为空
     255      */
     256     public E removeLast() {
     257         // 获取尾结点引用
     258         final Node<E> l = last;
     259         // 如果尾结点为空,则抛出无该元素异常
     260         if (l == null)
     261             throw new NoSuchElementException();
     262         // 删除尾结点,返回存储的元素
     263         return unlinkLast(l);
     264     }
     265 
     266     /**
     267      * 头部插入指定元素
     268      *
     269      * @param e 要添加的元素
     270      */
     271     public void addFirst(E e) {
     272         // 通过头插法来插入指定元素
     273         linkFirst(e);
     274     }
     275 
     276     /**
     277      * 尾部插入指定元素,该方法等价于add()
     278      *
     279      * @param e the element to add
     280      */
     281     public void addLast(E e) {
     282         linkLast(e);
     283     }
     284 
     285     /**
     286      * 判断是否包含指定元素
     287      *
     288      * @param o 判断链表是否包含的元素
     289      * @return {@code true} 如果链表包含指定的元素
     290      */
     291     public boolean contains(Object o) {
     292         //返回指定元素的索引位置,不存在就返回-1,然后比较返回bool值
     293         return indexOf(o) != -1;
     294     }
     295 
     296     /**
     297      * 获取元素数量
     298      *
     299      * @return 元素数量
     300      */
     301     public int size() {
     302         return size;
     303     }
     304 
     305     /**
     306      * 插入指定元素,返回操作结果,默认添加到末尾作为最后一个元素
     307      *
     308      * @param e 要添加到此链表中的元素
     309      * @return {@code true} (as specified by {@link Collection#add})
     310      */
     311     public boolean add(E e) {
     312         // 通过尾插法来插入指定元素
     313         linkLast(e);
     314         return true;
     315     }
     316 
     317     /**
     318      * 删除指定元素,默认从first节点开始,删除第一次出现的那个元素
     319      *
     320      * @param o 要从该列表中删除的元素(如果存在)
     321      * @return {@code true} 如果这个列表包含指定的元素
     322      */
     323     public boolean remove(Object o) {
     324         //会根据是否为null分开处理。若值不是null,会用到对象的equals()方法
     325         if (o == null) {
     326             // 遍历链表,查找到指定元素后删除该结点,返回true
     327             for (Node<E> x = first; x != null; x = x.next) {
     328                 if (x.item == null) {
     329                     unlink(x);
     330                     return true;
     331                 }
     332             }
     333         } else {
     334             for (Node<E> x = first; x != null; x = x.next) {
     335                 if (o.equals(x.item)) {
     336                     unlink(x);
     337                     return true;
     338                 }
     339             }
     340         }
     341         // 查找失败
     342         return false;
     343     }
     344 
     345     /**
     346      * 将集合插入到链表尾部,即开始索引位置为size
     347      *
     348      * @param c 包含要添加到此链表中的元素的集合
     349      * @return {@code true} 如果该链表因添加而改变
     350      * @throws NullPointerException 如果指定的集合是空的
     351      */
     352     public boolean addAll(Collection<? extends E> c) {
     353         return addAll(size, c);
     354     }
     355 
     356     /**
     357      * 将集合从指定位置开始插入
     358      *
     359      * @param index 在哪个索引处前插入指定集合中的第一个元素
     360      * @param c     包含要添加到此链表中的元素的集合
     361      * @return {@code true} 如果该链表因添加而改变
     362      * @throws IndexOutOfBoundsException {@inheritDoc}
     363      * @throws NullPointerException      如果指定的集合是空的
     364      */
     365     public boolean addAll(int index, Collection<? extends E> c) {
     366         //检查索引是否正确(0<=index<=size)
     367         checkPositionIndex(index);
     368         //得到元素数组
     369         Object[] a = c.toArray();
     370         //得到元素个数
     371         int numNew = a.length;
     372         //若没有元素要添加,直接返回false
     373         if (numNew == 0)
     374             return false;
     375         //succ指向当前需要插入节点的位置,pred指向其前一个节点
     376         Node<E> pred, succ;
     377         //如果是在末尾开始添加,当前节点后一个节点初始化为null,前一个节点为尾节点
     378         if (index == size) {
     379             succ = null;
     380             pred = last;
     381         } else {    //如果不是从末尾开始添加,当前位置的节点为指定位置的节点,前一个节点为要添加的节点的前一个节点
     382             succ = node(index);
     383             pred = succ.prev;
     384         }
     385         //遍历数组并添加到列表中
     386         for (Object o : a) {
     387             @SuppressWarnings("unchecked") E e = (E) o;
     388             //将元素值e,前继节点pred“封装”为一个新节点newNode
     389             Node<E> newNode = new Node<>(pred, e, null);
     390             //如果原链表为null,则新插入的节点作为链表首节点
     391             if (pred == null)
     392                 first = newNode;
     393             else
     394                 pred.next = newNode;    //如果存在前节点,前节点会向后指向新加的节点
     395             pred = newNode; //pred指针向后移动,指向下一个需插入节点位置的前一个节点
     396         }
     397         //如果是从最后开始添加的,则最后添加的节点成为尾节点
     398         if (succ == null) {
     399             last = pred;
     400         } else {
     401             pred.next = succ;   //如果不是从最后开始添加的,则最后添加的节点向后指向之前得到的后续第一个节点
     402             succ.prev = pred;   //当前,后续的第一个节点也应改为向前指向最后一个添加的节点
     403         }
     404 
     405         size += numNew;
     406         modCount++;
     407         return true;
     408     }
     409 
     410     /**
     411      * 删除所有元素
     412      */
     413     public void clear() {
     414         //遍历链表,删除所有结点,方便gc回收垃圾
     415         for (Node<E> x = first; x != null; ) {
     416             Node<E> next = x.next;
     417             x.item = null;
     418             x.next = null;
     419             x.prev = null;
     420             x = next;
     421         }
     422         // 首尾结点置空
     423         first = last = null;
     424         // 元素数量置0
     425         size = 0;
     426         modCount++;
     427     }
     428 
     429 
     430     // 位置访问操作
     431 
     432     /**
     433      * 获取指定位置的元素
     434      *
     435      * @param index 要返回的元素的索引
     436      * @return 该链表中指定位置的元素
     437      * @throws IndexOutOfBoundsException {@inheritDoc}
     438      */
     439     public E get(int index) {
     440         // 判断指定位置是否合法
     441         checkElementIndex(index);
     442         // 返回指定位置的元素
     443         return node(index).item;
     444     }
     445 
     446     /**
     447      * 修改指定位置的元素,返回之前元素
     448      *
     449      * @param index   要替换的元素的索引
     450      * @param element 要存储在指定位置的元素
     451      * @return 之前在指定位置的元素
     452      * @throws IndexOutOfBoundsException {@inheritDoc}
     453      */
     454     public E set(int index, E element) {
     455         // 判断指定位置是否合法
     456         checkElementIndex(index);
     457         // 获取指定位置的结点
     458         Node<E> x = node(index);
     459         // 获取该结点存储的元素
     460         E oldVal = x.item;
     461         // 修改该结点存储的元素
     462         x.item = element;
     463         // 返回该结点存储的之前的元素
     464         return oldVal;
     465     }
     466 
     467     /**
     468      * 在指定位置前插入指定元素
     469      *
     470      * @param index   指定元素将被插入的索引
     471      * @param element 要插入的元素
     472      * @throws IndexOutOfBoundsException {@inheritDoc}
     473      */
     474     public void add(int index, E element) {
     475         // 判断指定位置是否合法
     476         checkPositionIndex(index);
     477         // 如果指定位置在尾部,则通过尾插法来插入指定元素
     478         if (index == size)
     479             linkLast(element);
     480         else        //如果指定位置不是尾部,则添加到指定位置前
     481             linkBefore(element, node(index));
     482     }
     483 
     484     /**
     485      * 删除指定位置的元素,返回之前元素
     486      *
     487      * @param index 要删除的元素的索引
     488      * @return 之前在指定位置的元素
     489      * @throws IndexOutOfBoundsException {@inheritDoc}
     490      */
     491     public E remove(int index) {
     492         // 判断指定位置是否合法
     493         checkElementIndex(index);
     494         // 删除指定位置的结点,返回之前元素
     495         return unlink(node(index));
     496     }
     497 
     498     /**
     499      * 判断指定位置是否合法
     500      */
     501     private boolean isElementIndex(int index) {
     502         return index >= 0 && index < size;
     503     }
     504 
     505     /**
     506      * 判断迭代器遍历时或插入元素时指定位置是否合法
     507      */
     508     private boolean isPositionIndex(int index) {
     509         return index >= 0 && index <= size;
     510     }
     511 
     512     /**
     513      * 获取越界异常信息
     514      */
     515     private String outOfBoundsMsg(int index) {
     516         return "Index: " + index + ", Size: " + size;
     517     }
     518 
     519     /**
     520      * 判断指定位置是否合法
     521      *
     522      * @param index
     523      */
     524     private void checkElementIndex(int index) {
     525         if (!isElementIndex(index))
     526             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
     527     }
     528 
     529     /**
     530      * 判断指定位置是否合法
     531      *
     532      * @param index
     533      */
     534     private void checkPositionIndex(int index) {
     535         if (!isPositionIndex(index))
     536             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
     537     }
     538 
     539     /**
     540      * 获取指定下标的结点,index从0开始
     541      */
     542     Node<E> node(int index) {
     543         // 如果指定下标<一半元素数量,则从首结点开始遍历
     544         // 否则,从尾结点开始遍历
     545         if (index < (size >> 1)) {
     546             Node<E> x = first;
     547             for (int i = 0; i < index; i++)
     548                 x = x.next;
     549             return x;
     550         } else {
     551             Node<E> x = last;
     552             for (int i = size - 1; i > index; i--)
     553                 x = x.prev;
     554             return x;
     555         }
     556     }
     557 
     558     // 查询操作
     559 
     560     /**
     561      * 获取顺序下首次出现指定元素的位置
     562      * 如果返回结果是-1,则表示不存在该元素
     563      *
     564      * @param o 要查找的元素
     565      * @return the index of the first occurrence of the specified element in
     566      * this list, or -1 if this list does not contain the element
     567      */
     568     public int indexOf(Object o) {
     569         int index = 0;
     570         if (o == null) {
     571             // 遍历链表,顺序查找指定元素
     572             for (Node<E> x = first; x != null; x = x.next) {
     573                 if (x.item == null)
     574                     return index;
     575                 index++;
     576             }
     577         } else {
     578             for (Node<E> x = first; x != null; x = x.next) {
     579                 if (o.equals(x.item))
     580                     return index;
     581                 index++;
     582             }
     583         }
     584         return -1;
     585     }
     586 
     587     /**
     588      * 获取逆序下首次出现指定元素的位置
     589      * 如果返回结果是-1,则表示不存在该元素
     590      *
     591      * @param o 要查找的元素
     592      * @return the index of the last occurrence of the specified element in
     593      * this list, or -1 if this list does not contain the element
     594      */
     595     public int lastIndexOf(Object o) {
     596         int index = size;
     597         if (o == null) {
     598             // 遍历链表,逆序查找指定元素
     599             for (Node<E> x = last; x != null; x = x.prev) {
     600                 index--;
     601                 if (x.item == null)
     602                     return index;
     603             }
     604         } else {
     605             for (Node<E> x = last; x != null; x = x.prev) {
     606                 index--;
     607                 if (o.equals(x.item))
     608                     return index;
     609             }
     610         }
     611         return -1;
     612     }
     613 
     614     // 队列操作
     615 
     616     /**
     617      * 出队(从前端),获得第一个元素,不存在会返回null,不会删除元素(节点)
     618      * 获取首元素
     619      *
     620      * @return the head of this list, or {@code null} 如果链表为空
     621      * @since 1.5
     622      */
     623     public E peek() {
     624         final Node<E> f = first;
     625         // 如果首结点为空,则返回null
     626         // 否则,返回首结点存储的元素
     627         return (f == null) ? null : f.item;
     628     }
     629 
     630     /**
     631      * 出队(从前端),不删除元素,若为null会抛出异常而不是返回null
     632      * 获取首元素
     633      *
     634      * @return the head of this list
     635      * @throws NoSuchElementException 如果链表为空
     636      * @since 1.5
     637      */
     638     public E element() {
     639         // 返回首结点存储的元素
     640         return getFirst();
     641     }
     642 
     643     /**
     644      * 出队(从前端),如果不存在会返回null,存在的话会返回值并移除这个元素(节点)
     645      * 获取并删除首元素
     646      *
     647      * @return the head of this list, or {@code null} 如果链表为空
     648      * @since 1.5
     649      */
     650     public E poll() {
     651         // 获取首结点引用
     652         final Node<E> f = first;
     653         // 如果首结点为空,则返回null
     654         // 否则,删除首结点,返回首结点存储的元素
     655         return (f == null) ? null : unlinkFirst(f);
     656     }
     657 
     658     /**
     659      * 出队(从前端),如果不存在会抛出异常而不是返回null,存在的话会返回值并移除这个元素(节点)
     660      * 获取并删除首元素
     661      *
     662      * @return the head of this list
     663      * @throws NoSuchElementException 如果链表为空
     664      * @since 1.5
     665      */
     666     public E remove() {
     667         // 删除首结点,返回首结点存储的元素
     668         return removeFirst();
     669     }
     670 
     671     /**
     672      * 入队(从后端),始终返回true
     673      *
     674      * @param e the element to add
     675      * @return {@code true} (as specified by {@link Queue#offer})
     676      * @since 1.5
     677      */
     678     public boolean offer(E e) {
     679         // 通过尾插法插入指定元素,返回操作结果
     680         return add(e);
     681     }
     682 
     683     // 双端队列操作
     684 
     685     /**
     686      * 入队(从前端),始终返回true
     687      *
     688      * @param e 要插入的元素
     689      * @return {@code true} (as specified by {@link Deque#offerFirst})
     690      * @since 1.6
     691      */
     692     public boolean offerFirst(E e) {
     693         //  通过尾插法来插入指定元素
     694         addFirst(e);
     695         return true;
     696     }
     697 
     698     /**
     699      * 入队(从后端),始终返回true
     700      *
     701      * @param e 要插入的元素
     702      * @return {@code true} (as specified by {@link Deque#offerLast})
     703      * @since 1.6
     704      */
     705     public boolean offerLast(E e) {
     706         // 通过尾插法来插入指定元素
     707         addLast(e);
     708         return true;
     709     }
     710 
     711     /**
     712      * 出队(从后端),获得最后一个元素,不存在会返回null,不会删除元素(节点)
     713      *
     714      * @return the first element of this list, or {@code null}
     715      * 如果链表为空
     716      * @since 1.6
     717      */
     718     public E peekFirst() {
     719         // 获取首结点引用
     720         final Node<E> f = first;
     721         // 如果首结点为空,则返回null
     722         // 否则,返回首结点存储的元素
     723         return (f == null) ? null : f.item;
     724     }
     725 
     726     /**
     727      * 出队(从后端),获得最后一个元素,不存在会返回null,不会删除元素(节点)
     728      *
     729      * @return the last element of this list, or {@code null}
     730      * 如果链表为空
     731      * @since 1.6
     732      */
     733     public E peekLast() {
     734         // 获取尾结点引用
     735         final Node<E> l = last;
     736         // 如果尾结点为空,则返回null
     737         // 否则,返回尾结点存储的元素
     738         return (l == null) ? null : l.item;
     739     }
     740 
     741     /**
     742      * 出队(从前端),获得第一个元素,不存在会返回null,会删除元素(节点)
     743      *
     744      * @return the first element of this list, or {@code null} if
     745      * this list is empty
     746      * @since 1.6
     747      */
     748     public E pollFirst() {
     749         // 获取首结点引用
     750         final Node<E> f = first;
     751         // 如果首结点为空,则返回null
     752         // 否则,删除首结点,返回首结点存储的元素
     753         return (f == null) ? null : unlinkFirst(f);
     754     }
     755 
     756     /**
     757      * 出队(从后端),获得最后一个元素,不存在会返回null,会删除元素(节点)
     758      *
     759      * @return the last element of this list, or {@code null} if
     760      * this list is empty
     761      * @since 1.6
     762      */
     763     public E pollLast() {
     764         // 获取尾结点引用
     765         final Node<E> l = last;
     766         // 如果尾结点为空,则返回null
     767         // 否则,删除尾结点,返回尾结点存储的元素
     768         return (l == null) ? null : unlinkLast(l);
     769     }
     770 
     771     /**
     772      * 入栈,从前面添加
     773      *
     774      * @param e the element to push
     775      * @since 1.6
     776      */
     777     public void push(E e) {
     778         // 通过头插法来插入指定元素
     779         addFirst(e);
     780     }
     781 
     782     /**
     783      * 出栈,返回栈顶元素,从前面移除(会删除)
     784      *
     785      * @return the element at the front of this list (which is the top
     786      * of the stack represented by this list)
     787      * @throws NoSuchElementException 如果链表为空
     788      * @since 1.6
     789      */
     790     public E pop() {
     791         // 删除首结点,返回首结点存储的元素
     792         return removeFirst();
     793     }
     794 
     795     /**
     796      * 删除顺序下首次出现的指定元素,返回操作结果
     797      *
     798      * @param o 要从该列表中删除的元素(如果存在)
     799      * @return {@code true} 如果链表包含指定的元素
     800      * @since 1.6
     801      */
     802     public boolean removeFirstOccurrence(Object o) {
     803         // 删除顺序下首次出现的指定元素对应的结点,返回操作结果
     804         return remove(o);
     805     }
     806 
     807     /**
     808      * 删除逆序下首次出现的指定元素,返回操作结果
     809      *
     810      * @param o 要从该列表中删除的元素(如果存在)
     811      * @return {@code true} 如果链表包含指定的元素
     812      * @since 1.6
     813      */
     814     public boolean removeLastOccurrence(Object o) {
     815         //由于LinkedList中允许存放null,因此下面通过两种情况来分别处理
     816         if (o == null) {
     817             // 遍历链表,从尾结点开始查找指定元素
     818             // 如果查找成功,删除该结点,返回true
     819             for (Node<E> x = last; x != null; x = x.prev) {
     820                 if (x.item == null) {
     821                     unlink(x);
     822                     return true;
     823                 }
     824             }
     825         } else {
     826             for (Node<E> x = last; x != null; x = x.prev) {
     827                 if (o.equals(x.item)) {
     828                     unlink(x);
     829                     return true;
     830                 }
     831             }
     832         }
     833         // 查找失败
     834         return false;
     835     }
     836 
     837     /**
     838      * Returns a list-iterator of the elements in this list (in proper
     839      * sequence), starting at the specified position in the list.
     840      * Obeys the general contract of {@code List.listIterator(int)}.<p>
     841      * <p>
     842      * The list-iterator is <i>fail-fast</i>: if the list is structurally
     843      * modified at any time after the Iterator is created, in any way except
     844      * through the list-iterator's own {@code remove} or {@code add}
     845      * methods, the list-iterator will throw a
     846      * {@code ConcurrentModificationException}.  Thus, in the face of
     847      * concurrent modification, the iterator fails quickly and cleanly, rather
     848      * than risking arbitrary, non-deterministic behavior at an undetermined
     849      * time in the future.
     850      *
     851      * @param index index of the first element to be returned from the
     852      *              list-iterator (by a call to {@code next})
     853      * @return a ListIterator of the elements in this list (in proper
     854      * sequence), starting at the specified position in the list
     855      * @throws IndexOutOfBoundsException {@inheritDoc}
     856      * @see List#listIterator(int)
     857      */
     858     public ListIterator<E> listIterator(int index) {
     859         checkPositionIndex(index);
     860         return new ListItr(index);
     861     }
     862 
     863     private class ListItr implements ListIterator<E> {
     864         private Node<E> lastReturned;
     865         private Node<E> next;
     866         private int nextIndex;
     867         private int expectedModCount = modCount;
     868 
     869         ListItr(int index) {
     870             // assert isPositionIndex(index);
     871             next = (index == size) ? null : node(index);
     872             nextIndex = index;
     873         }
     874 
     875         public boolean hasNext() {
     876             return nextIndex < size;
     877         }
     878 
     879         public E next() {
     880             checkForComodification();
     881             if (!hasNext())
     882                 throw new NoSuchElementException();
     883 
     884             lastReturned = next;
     885             next = next.next;
     886             nextIndex++;
     887             return lastReturned.item;
     888         }
     889 
     890         public boolean hasPrevious() {
     891             return nextIndex > 0;
     892         }
     893 
     894         public E previous() {
     895             checkForComodification();
     896             if (!hasPrevious())
     897                 throw new NoSuchElementException();
     898 
     899             lastReturned = next = (next == null) ? last : next.prev;
     900             nextIndex--;
     901             return lastReturned.item;
     902         }
     903 
     904         public int nextIndex() {
     905             return nextIndex;
     906         }
     907 
     908         public int previousIndex() {
     909             return nextIndex - 1;
     910         }
     911 
     912         public void remove() {
     913             checkForComodification();
     914             if (lastReturned == null)
     915                 throw new IllegalStateException();
     916 
     917             Node<E> lastNext = lastReturned.next;
     918             unlink(lastReturned);
     919             if (next == lastReturned)
     920                 next = lastNext;
     921             else
     922                 nextIndex--;
     923             lastReturned = null;
     924             expectedModCount++;
     925         }
     926 
     927         public void set(E e) {
     928             if (lastReturned == null)
     929                 throw new IllegalStateException();
     930             checkForComodification();
     931             lastReturned.item = e;
     932         }
     933 
     934         public void add(E e) {
     935             checkForComodification();
     936             lastReturned = null;
     937             if (next == null)
     938                 linkLast(e);
     939             else
     940                 linkBefore(e, next);
     941             nextIndex++;
     942             expectedModCount++;
     943         }
     944 
     945         public void forEachRemaining(Consumer<? super E> action) {
     946             Objects.requireNonNull(action);
     947             while (modCount == expectedModCount && nextIndex < size) {
     948                 action.accept(next.item);
     949                 lastReturned = next;
     950                 next = next.next;
     951                 nextIndex++;
     952             }
     953             checkForComodification();
     954         }
     955 
     956         final void checkForComodification() {
     957             if (modCount != expectedModCount)
     958                 throw new ConcurrentModificationException();
     959         }
     960     }
     961 
     962     /**
     963      * 节点的数据结构,包含前后节点的引用和当前节点
     964      *
     965      * @param <E>
     966      */
     967     private static class Node<E> {
     968         // 存储的元素
     969         E item;
     970         // 后继结点
     971         Node<E> next;
     972         // 前驱结点
     973         Node<E> prev;
     974 
     975         // 前驱结点、存储的元素和后继结点作为参数的构造方法
     976         Node(Node<E> prev, E element, Node<E> next) {
     977             this.item = element;
     978             this.next = next;
     979             this.prev = prev;
     980         }
     981     }
     982 
     983     /**
     984      * 返回迭代器
     985      *
     986      * @since 1.6
     987      */
     988     public Iterator<E> descendingIterator() {
     989         return new DescendingIterator();
     990     }
     991 
     992     /**
     993      * 因为采用链表实现,所以迭代器很简单
     994      */
     995     private class DescendingIterator implements Iterator<E> {
     996         private final ListItr itr = new ListItr(size());
     997 
     998         public boolean hasNext() {
     999             return itr.hasPrevious();
    1000         }
    1001 
    1002         public E next() {
    1003             return itr.previous();
    1004         }
    1005 
    1006         public void remove() {
    1007             itr.remove();
    1008         }
    1009     }
    1010 
    1011     /**
    1012      * 父类克隆方法
    1013      */
    1014     @SuppressWarnings("unchecked")
    1015     private LinkedList<E> superClone() {
    1016         try {
    1017             return (LinkedList<E>) super.clone();
    1018         } catch (CloneNotSupportedException e) {
    1019             throw new InternalError(e);
    1020         }
    1021     }
    1022 
    1023     /**
    1024      * 克隆,浅拷贝
    1025      *
    1026      * @return a shallow copy of this {@code LinkedList} instance
    1027      */
    1028     public Object clone() {
    1029         LinkedList<E> clone = superClone();
    1030 
    1031         // 链表初始化
    1032         clone.first = clone.last = null;
    1033         clone.size = 0;
    1034         clone.modCount = 0;
    1035 
    1036         // 插入结点
    1037         for (Node<E> x = first; x != null; x = x.next)
    1038             clone.add(x.item);
    1039         // 返回克隆后的对象引用
    1040         return clone;
    1041     }
    1042 
    1043     /**
    1044      * Returns an array containing all of the elements in this list
    1045      * in proper sequence (from first to last element).
    1046      * <p>
    1047      * <p>The returned array will be "safe" in that no references to it are
    1048      * maintained by this list.  (In other words, this method must allocate
    1049      * a new array).  The caller is thus free to modify the returned array.
    1050      * <p>
    1051      * <p>This method acts as bridge between array-based and collection-based
    1052      * APIs.
    1053      *
    1054      * @return an array containing all of the elements in this list
    1055      * in proper sequence
    1056      */
    1057     public Object[] toArray() {
    1058         Object[] result = new Object[size];
    1059         int i = 0;
    1060         for (Node<E> x = first; x != null; x = x.next)
    1061             result[i++] = x.item;
    1062         return result;
    1063     }
    1064 
    1065     /**
    1066      * Returns an array containing all of the elements in this list in
    1067      * proper sequence (from first to last element); the runtime type of
    1068      * the returned array is that of the specified array.  If the list fits
    1069      * in the specified array, it is returned therein.  Otherwise, a new
    1070      * array is allocated with the runtime type of the specified array and
    1071      * the size of this list.
    1072      * <p>
    1073      * <p>If the list fits in the specified array with room to spare (i.e.,
    1074      * the array has more elements than the list), the element in the array
    1075      * immediately following the end of the list is set to {@code null}.
    1076      * (This is useful in determining the length of the list <i>only</i> if
    1077      * the caller knows that the list does not contain any null elements.)
    1078      * <p>
    1079      * <p>Like the {@link #toArray()} method, this method acts as bridge between
    1080      * array-based and collection-based APIs.  Further, this method allows
    1081      * precise control over the runtime type of the output array, and may,
    1082      * under certain circumstances, be used to save allocation costs.
    1083      * <p>
    1084      * <p>Suppose {@code x} is a list known to contain only strings.
    1085      * The following code can be used to dump the list into a newly
    1086      * allocated array of {@code String}:
    1087      * <p>
    1088      * <pre>
    1089      *     String[] y = x.toArray(new String[0]);</pre>
    1090      * <p>
    1091      * Note that {@code toArray(new Object[0])} is identical in function to
    1092      * {@code toArray()}.
    1093      *
    1094      * @param a the array into which the elements of the list are to
    1095      *          be stored, if it is big enough; otherwise, a new array of the
    1096      *          same runtime type is allocated for this purpose.
    1097      * @return an array containing the elements of the list
    1098      * @throws ArrayStoreException  if the runtime type of the specified array
    1099      *                              is not a supertype of the runtime type of every element in
    1100      *                              this list
    1101      * @throws NullPointerException if the specified array is null
    1102      */
    1103     @SuppressWarnings("unchecked")
    1104     public <T> T[] toArray(T[] a) {
    1105         if (a.length < size)
    1106             a = (T[]) java.lang.reflect.Array.newInstance(
    1107                     a.getClass().getComponentType(), size);
    1108         int i = 0;
    1109         Object[] result = a;
    1110         for (Node<E> x = first; x != null; x = x.next)
    1111             result[i++] = x.item;
    1112 
    1113         if (a.length > size)
    1114             a[size] = null;
    1115 
    1116         return a;
    1117     }
    1118 
    1119     private static final long serialVersionUID = 876323262645176354L;
    1120 
    1121     /**
    1122      * 序列化
    1123      */
    1124     private void writeObject(java.io.ObjectOutputStream s)
    1125             throws java.io.IOException {
    1126         // 默认序列化
    1127         s.defaultWriteObject();
    1128 
    1129         // 写入元素数量
    1130         s.writeInt(size);
    1131 
    1132         // 遍历链表,写入所有元素
    1133         for (Node<E> x = first; x != null; x = x.next)
    1134             s.writeObject(x.item);
    1135     }
    1136 
    1137     /**
    1138      * 反序列化
    1139      */
    1140     @SuppressWarnings("unchecked")
    1141     private void readObject(java.io.ObjectInputStream s)
    1142             throws java.io.IOException, ClassNotFoundException {
    1143         // 默认反序列化
    1144         s.defaultReadObject();
    1145 
    1146         // 读取元素数量
    1147         int size = s.readInt();
    1148 
    1149         // 遍历链表,读取所有元素并尾部插入
    1150         for (int i = 0; i < size; i++)
    1151             linkLast((E) s.readObject());
    1152     }
    1153 
    1154     /**
    1155      * Creates a <em><a href="Spliterator.html#binding">late-binding</a></em>
    1156      * and <em>fail-fast</em> {@link Spliterator} over the elements in this
    1157      * list.
    1158      * <p>
    1159      * <p>The {@code Spliterator} reports {@link Spliterator#SIZED} and
    1160      * {@link Spliterator#ORDERED}.  Overriding implementations should document
    1161      * the reporting of additional characteristic values.
    1162      *
    1163      * @return a {@code Spliterator} over the elements in this list
    1164      * @implNote The {@code Spliterator} additionally reports {@link Spliterator#SUBSIZED}
    1165      * and implements {@code trySplit} to permit limited parallelism..
    1166      * @since 1.8
    1167      */
    1168     @Override
    1169     public Spliterator<E> spliterator() {
    1170         return new LLSpliterator<E>(this, -1, 0);
    1171     }
    1172 
    1173     /**
    1174      * A customized variant of Spliterators.IteratorSpliterator
    1175      */
    1176     static final class LLSpliterator<E> implements Spliterator<E> {
    1177         static final int BATCH_UNIT = 1 << 10;  // batch array size increment
    1178         static final int MAX_BATCH = 1 << 25;  // max batch array size;
    1179         final LinkedList<E> list; // null OK unless traversed
    1180         Node<E> current;      // current node; null until initialized
    1181         int est;              // size estimate; -1 until first needed
    1182         int expectedModCount; // initialized when est set
    1183         int batch;            // batch size for splits
    1184 
    1185         LLSpliterator(LinkedList<E> list, int est, int expectedModCount) {
    1186             this.list = list;
    1187             this.est = est;
    1188             this.expectedModCount = expectedModCount;
    1189         }
    1190 
    1191         final int getEst() {
    1192             int s; // force initialization
    1193             final LinkedList<E> lst;
    1194             if ((s = est) < 0) {
    1195                 if ((lst = list) == null)
    1196                     s = est = 0;
    1197                 else {
    1198                     expectedModCount = lst.modCount;
    1199                     current = lst.first;
    1200                     s = est = lst.size;
    1201                 }
    1202             }
    1203             return s;
    1204         }
    1205 
    1206         public long estimateSize() {
    1207             return (long) getEst();
    1208         }
    1209 
    1210         public Spliterator<E> trySplit() {
    1211             Node<E> p;
    1212             int s = getEst();
    1213             if (s > 1 && (p = current) != null) {
    1214                 int n = batch + BATCH_UNIT;
    1215                 if (n > s)
    1216                     n = s;
    1217                 if (n > MAX_BATCH)
    1218                     n = MAX_BATCH;
    1219                 Object[] a = new Object[n];
    1220                 int j = 0;
    1221                 do {
    1222                     a[j++] = p.item;
    1223                 } while ((p = p.next) != null && j < n);
    1224                 current = p;
    1225                 batch = j;
    1226                 est = s - j;
    1227                 return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);
    1228             }
    1229             return null;
    1230         }
    1231 
    1232         public void forEachRemaining(Consumer<? super E> action) {
    1233             Node<E> p;
    1234             int n;
    1235             if (action == null) throw new NullPointerException();
    1236             if ((n = getEst()) > 0 && (p = current) != null) {
    1237                 current = null;
    1238                 est = 0;
    1239                 do {
    1240                     E e = p.item;
    1241                     p = p.next;
    1242                     action.accept(e);
    1243                 } while (p != null && --n > 0);
    1244             }
    1245             if (list.modCount != expectedModCount)
    1246                 throw new ConcurrentModificationException();
    1247         }
    1248 
    1249         public boolean tryAdvance(Consumer<? super E> action) {
    1250             Node<E> p;
    1251             if (action == null) throw new NullPointerException();
    1252             if (getEst() > 0 && (p = current) != null) {
    1253                 --est;
    1254                 E e = p.item;
    1255                 current = p.next;
    1256                 action.accept(e);
    1257                 if (list.modCount != expectedModCount)
    1258                     throw new ConcurrentModificationException();
    1259                 return true;
    1260             }
    1261             return false;
    1262         }
    1263 
    1264         public int characteristics() {
    1265             return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
    1266         }
    1267     }
    1268 
    1269 }
  • 相关阅读:
    网络文件传输方式
    ETL利器Kettle
    oracle 字符处理
    ORACLE临时表空间
    Count(*)或者Count(1)或者Count([列]) 区别
    Oracle trunc()函数的用法
    DATE 日期格式
    oracle 异常
    物化视图
    域名和端口
  • 原文地址:https://www.cnblogs.com/wupeixuan/p/8620164.html
Copyright © 2011-2022 走看看