JDK之LinkedList原始碼解讀(一)
阿新 • • 發佈:2019-01-13
目錄
LinkedList由一系列Node節點組成,每一個節點指向前一個節點和後一個節點的引用,因此是一個雙向連結串列。
建構函式
一個是無參的建構函式,一個引數是Collection c的建構函式。第二個建構函式呼叫addAll(c)方法。
size是LinkedList的元素個數。
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; pred = last; } else { succ = node(index); pred = succ.prev; } for (Object o : a) { @SuppressWarnings("unchecked") E e = (E) o; Node<E> newNode = new Node<>(pred, e, null); if (pred == null) first = newNode; else pred.next = newNode; pred = newNode; } if (succ == null) { last = pred; } else { pred.next = succ; succ.prev = pred; } size += numNew; modCount++; return true; }
先校驗index的正確性 checkPositionIndex(index)
private void checkPositionIndex(int index) { if (!isPositionIndex(index)) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private boolean isPositionIndex(int index) { return index >= 0 && index <= size; }
如果index小於0或者大於LinkedList的長度,則丟擲越界異常。
linkFirst(E e)
private void linkFirst(E e) { //將頭結點賦值給臨時變數f final Node<E> f = first; //建立一個新節點,它的前任節點為null,節點資料是傳入的引數E e, 後續節點就是原來的頭結點。這樣一來,這個節點就變成了新的頭結點 final Node<E> newNode = new Node<>(null, e, f); //first再重新指向新的頭結點 first = newNode; //假如原先的頭結點為null,說明原LinkedList是空的,那麼last也指向這個新節點,因為這時候只有一個節點,所以該節點既是頭結點,也是尾節點 if (f == null) last = newNode; else f.prev = newNode; //LinkedList長度加1 size++; modCount++; }
作用:將新物件插入到LinkedList的頭部,作為新的頭結點。
linkLast(E e)
void linkLast(E e) {
//將尾節點賦值給臨時變數l
final Node<E> l = last;
//建立一個新節點,它的前任節點是原來的尾結點,節點資料是傳入的引數E e, 後續節點為null。這樣一來,這個節點就變成了新的頭結點
final Node<E> newNode = new Node<>(l, e, null);
//last再重新指向新的尾結點
last = newNode;
//假如原先的尾結點為null,說明原LinkedList是空的,那麼first也指向這個新節點,因為這時候只有一個節點,所以該節點既是頭結點,也是尾節點
if (l == null)
first = newNode;
else
l.next = newNode;
//LinkedList長度加1
size++;
modCount++;
}
作用:將新物件插入到LinkedList的尾部,作為新的尾結點。
linkBefore(E e, Node<E> succ)
void linkBefore(E e, Node<E> succ) {
// assert succ != null;
final Node<E> pred = succ.prev;
//建立一個新節點,它的前任節點是指定節點succ的前任節點,節點資料是傳入的引數E e, 後續節點是該指定節點succ。這樣一來,這個節點就插入到該節點succ的前面了
final Node<E> newNode = new Node<>(pred, e, succ);
//該節點succ前任節點變成了剛才插入的新節點了
succ.prev = newNode;
//假如原先的尾結點為null,說明原LinkedList是空的,那麼first也指向這個新節點,因為這時候只有一個節點,所以該節點既是頭結點,也是尾節點
if (pred == null)
first = newNode;
else
pred.next = newNode;
//LinkedList長度加1
size++;
modCount++;
}
作用:將新物件插入到LinkedList的指定節點前面。