java8LinkedList原始碼閱讀解析
/**
* Constructs an empty list.
*/
public LinkedList() {
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public LinkedList(Collection<? extends E> c) {
// 呼叫無參構造,其實就是個空方法
this();
// 新增全部元素至 LinkedList
addAll(c);
}
//addAll 方法,此時對於新建的 LinkedList 例項, size=0
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
/**
* 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);
// 將 Collection 入參轉換為陣列
Object[] a = c.toArray();
// 檢查入參中是否包含元素,如果返回 false ,說明有參構造的 Collection 引數不包含元素
int numNew = a.length;
if (numNew == 0)
return false;
// 連結串列節點 Node
Node<E> pred, succ;
// 驗證 index 是否 ==size ,如果等於,則在連結串列 last 元素後追加新元素
if (index == size) {
succ = null;
pred = last;
} else {
// 如不等於,則獲取下標為 index 元素,
succ = node(index);
pred = succ.prev;
}
// 迴圈入參中的元素
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
// 新建一個節點,外匯跟單gendan5.com不包含 next 下一節點
Node<E> newNode = new Node<>(pred, e, null);
如果新建節點 next==null ,說明是頭節點
if (pred == null)
first = newNode;
else
// 否則,將前節點的 next 引用指向新建節點
pred.next = newNode;
pred = newNode;
}
// 迴圈結束,如果傳入 index 為連結串列長度,最後一次迴圈得到 pred 就是尾節點
if (succ == null) {
last = pred;
} else {
// 如果 index 不等於 size ,說明是從中間插入的,最後一個元素也有下一節點
// 該下一節點就是之前下標為 index 的元素
pred.next = succ;
succ.prev = pred;
}
// 連結串列元素數量增加
size += numNew;
// 迭代器需要用到的修改次數,若不為 0 ,使用迭代器遍歷會報錯
modCount++;
return true;
}
// 越界檢查
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
// 越界檢查
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
// 連結串列中節點,包含自身引用及前後節點引用
// 這樣,連結串列中的節點便是包含前一節點和後一節點引用 ( 除去首尾節點 )
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
/**
* Returns the (non-null) Node at the specified element index.
* 返回指定位置的非空節點
* 節點如果為空
*/
Node<E> node(int index) {
// assert isElementIndex(index);
//index 大於 size 的一半,則從連結串列頭部開始向下遍歷處理
if (index < (size >> 1)) {
Node<E> x = first;
// 從頭遍歷,找到下標為 index 的元素(同陣列的下標)
// 也就是說秒如果 index=4 ,得到的,是第五個元素
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
// 否則,則從連結串列尾部開始向上遍歷處理
Node<E> x = last;
// 從尾巴節點的前節點開始找,假如 size=8.index = 6. 實際得到的,相當於陣列中下標為 7 的元素
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946337/viewspace-2776807/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Laravel 原始碼閱讀指南 -- Cookie 原始碼解析Laravel原始碼Cookie
- 【原始碼閱讀】AndPermission原始碼閱讀原始碼
- Vuex 原始碼解析(如何閱讀原始碼實踐篇)Vue原始碼
- Spring原始碼閱讀-IoC容器解析Spring原始碼
- ThinkPHP6 原始碼閱讀(六):Url 解析PHP原始碼
- Spring 原始碼閱讀之標籤解析Spring原始碼
- 【原始碼閱讀】Glide原始碼閱讀之with方法(一)原始碼IDE
- 【原始碼閱讀】Glide原始碼閱讀之into方法(三)原始碼IDE
- BufferedOutputStream的快取功能解析(原始碼閱讀)快取原始碼
- ReactorKit原始碼閱讀React原始碼
- AQS原始碼閱讀AQS原始碼
- CountDownLatch原始碼閱讀CountDownLatch原始碼
- HashMap 原始碼閱讀HashMap原始碼
- delta原始碼閱讀原始碼
- 原始碼閱讀-HashMap原始碼HashMap
- NGINX原始碼閱讀Nginx原始碼
- Mux 原始碼閱讀UX原始碼
- HashMap原始碼閱讀HashMap原始碼
- fuzz原始碼閱讀原始碼
- RunLoop 原始碼閱讀OOP原始碼
- express 原始碼閱讀Express原始碼
- muduo原始碼閱讀原始碼
- stack原始碼閱讀原始碼
- 【原始碼閱讀】Glide原始碼閱讀之load方法(二)原始碼IDE
- ThinkPHP6 原始碼閱讀(五):多應用解析PHP原始碼
- 完全解析!Bert & Transformer 閱讀理解原始碼詳解ORM原始碼
- TiCDC 原始碼閱讀(四)TiCDC Scheduler 工作原理解析原始碼
- PostgreSQL 原始碼解讀(3)- 如何閱讀原始碼SQL原始碼
- JDK原始碼閱讀:Object類閱讀筆記JDK原始碼Object筆記
- Laravel 原始碼閱讀 - QueueLaravel原始碼
- Vollery原始碼閱讀(—)原始碼
- 使用OpenGrok閱讀原始碼原始碼
- 如何閱讀Java原始碼?Java原始碼
- buffer 原始碼包閱讀原始碼
- 原始碼閱讀技巧篇原始碼
- 如何閱讀框架原始碼框架原始碼
- 再談原始碼閱讀原始碼
- Laravel 原始碼閱讀 - EloquentLaravel原始碼