JDK源碼-LinkedList中addAll解讀

讀JDK源碼之時,看到LinkedList的addAll源碼,恕本人愚頓,真心覺得寫得太優美了,所以分享一下。

/**
     * 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
     */
    public boolean addAll(int index, Collection<? extends E> c) {
        checkPositionIndex(index);

        Object[] a = c.toArray();//形態轉換,方便後期操作.
        int numNew = a.length;
        if (numNew == 0)
            return false;
        
        //注意,此時前後節點的設計,對後期批量插入十分關鍵,是美的前提.
        Node<E> pred, succ;
        if (index == size) {
            succ = null;//當在鏈表最後插入時,last變爲前節點,後繼節點爲空.
            pred = last;
        } else {
            succ = node(index);//在當前節點的前面插入整個數組.
            pred = succ.prev;
        }

        for (Object o : a) {
            @SuppressWarnings("unchecked") E e = (E) o;
       //每個節點有三個特徵,pred, element, succ.注意三個元素的變化.
            Node<E> newNode = new Node<>(pred, e, null);//新建節點,並指向pred.
            if (pred == null)
                first = newNode;
            else
     //對pred節點,讓其指向newNode.至此,newNode與前節點的雙邊指向關係建立.此時後節點還沒出現.
            pred.next = newNode;
    //令newNodeo爲即將插入節點的前節點,在一個循環中,newNode將建立與後節點的雙邊指向關係.
            pred = newNode;
        }
    //如此循環結束後,只剩最後一個節點的雙邊指向關係沒有建立.

        if (succ == null) {
            last = pred;
        } else {//建立最後一個節點的指向.
            pred.next = succ;
            succ.prev = pred;
        }

        size += numNew;//節點數增加.
        modCount++;//鏈表修改次數增加.
        return true;
    }

有一種車間流水線的感覺,如此順利的大批量插入節點。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章