读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;
}
有一种车间流水线的感觉,如此顺利的大批量插入节点。