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

有一种车间流水线的感觉,如此顺利的大批量插入节点。

发布了12 篇原创文章 · 获赞 14 · 访问量 4649

猜你喜欢

转载自blog.csdn.net/cheetahzhang/article/details/103554759