讀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;
}
有一種車間流水線的感覺,如此順利的大批量插入節點。