-
list.add 方法
//add 方法 public boolean add(E e) { linkLast(e);//add 實現邏輯 return true; } //linkLast 方法實現 void linkLast(E e) { final Node<E> l = last;//記錄最後的一個Node final Node<E> newNode = new Node<>(l, e, null);//定義newNode 設定newNode 的前指針 //爲 lastNode , 後指針爲 null last = newNode; // 將newNode 賦值爲 last if (l == null) // 判斷 定義的 l 是否爲空 first = newNode; // 爲空當前 last 爲firstNode else l.next = newNode; // 設定 newNode 爲 l 的下一個Node size++; //size +1 modCount++; // 操作 +1 } // new Node<>() 方法 鏈表的存儲方式 private static class Node<E> { E item; //value Node<E> next; // 下一個Node 後指針 Node<E> prev; // 上一個Node 前指針 Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
-
list.addAll 方法
// addAll 方法 public boolean addAll(Collection<? extends E> c) { return addAll(size, c);// addAll 實現邏輯 } // addAll 方法實現 LinkedList.addAll 和 ArrayList.addAll 方法比較 效率上 // ArrayList.addAll 方法 效率更好 public boolean addAll(int index, Collection<? extends E> c) { checkPositionIndex(index);// 判斷當前index 是否超出實際size Object[] a = c.toArray();// 轉換爲數組的形式 方法使用循環操作 int numNew = a.length; // 定義需要新添加的數量 if (numNew == 0)// 判斷當前新添加的數組是否爲空 return false; // Node(index) 的 前指針節點 後指針節點 Node<E> pred, succ; if (index == size) { // 判斷是否末尾追加數據 succ = null; // 末尾Node 的後指針爲空 pred = last; // 前置指針爲 last } else { succ = node(index); // 取當前node(index) 位置的數據爲後指針 pred = succ.prev;// 前指針 爲 node(index) 節點的上一個 } //循環操作 對比ArrayList 這裏需要添加Node 的前後指針操作 效率較低 for (Object o : a) { @SuppressWarnings("unchecked") E e = (E) o; Node<E> newNode = new Node<>(pred, e, null);// 執行node 的初始操作 if (pred == null)// 判斷是否是空數組的add操作 first = newNode;// 將newNode 賦值爲 first else pred.next = newNode;// 數據中間 add 數據 設定 newNode 爲pred的nextNode pred = newNode;//重新定義pred } if (succ == null) {// 判斷node(index) 是否是空 last = pred;// 重新定義last(表明是末尾追加的數據) } else { pred.next = succ;// 定義 newNode 的後指針爲 node(index) succ.prev = pred;// 定義 node(index) 的前指針爲 newNode } size += numNew; // size + numNew (實際數組的總個數) modCount++;//操作+1 return true; }
-
list.remove 方法
// remove() 方法 remove 第一個Node 數據 public E remove() { return removeFirst(); } // removeFirst 方法實現 public E removeFirst() { final Node<E> f = first;// 記錄第一條數據 if (f == null)// 如果第一條數據是空 拋出異常 throw new NoSuchElementException(); return unlinkFirst(f);// 執行 remove 方法 } // unlinkFirst 方法實現 private E unlinkFirst(Node<E> f) { // assert f == first && f != null; final E element = f.item;// 定義 f 的element final Node<E> next = f.next;// 將 f.next 數據賦值爲 next 需要將 next 設置爲 null f.item = null;// 設置 item 爲 null f.next = null; // 設置 next 爲 null first = next; // 將 原本第二的 Node 設爲 第一個 if (next == null)// 判斷當前 f 節點是否是 lastNode last = null;// 是lastNode 設置 last 爲 null else next.prev = null; // 不是lastNode 設置 next.prev 爲null (因爲remove 了 first 從新 // 定義的 first 的 prev = null) size--;// 數組 size -1 modCount++; // 操作 +1 return element;// 返回當前 remove 的 element }
// remove(int index) 方法 public E remove(int index) { checkElementIndex(index);// 判斷當前index 是否超出 數組本身的size return unlink(node(index));// 執行 node(index) 數據的 remove 操作 } // node(index) 方法實現 Node<E> node(int index) { // assert isElementIndex(index); // 判斷當前index 是否在size/2(>>1:除以2) 之前的位置 (提高查找效率) if (index < (size >> 1)) { Node<E> x = first;//在前一半的位置 從開始找 for (int i = 0; i < index; i++)//循環定位查找 x = x.next; return x; } else { Node<E> x = last;//在後一半的位置 從末尾找 for (int i = size - 1; i > index; i--)//循環定位查找 x = x.prev; return x; } } // unlink 方法 E unlink(Node<E> x) { // assert x != null; final E element = x.item;// 需要 remove 的數據 x final Node<E> next = x.next;// x 的後指針數據 final Node<E> prev = x.prev;// x 的前指針數據 if (prev == null) {// 判斷x.prev 是否爲空 爲空表明 x 爲 first first = next;// 定義 x.next 爲first } else { prev.next = next;// 從新定義 x.prev.next 爲 x.next x.prev = null;// 將x.prev 定義爲 null 執行remove 操作 } if (next == null) {// 判斷x.next 是否爲空 爲空表明 x 爲 last last = prev;// 直接設置 x.prev 爲last } else { next.prev = prev;// 從新定義 x.next.prev 爲 x.prev x.next = null;// 將x.next 定義爲 null 執行 remove 操作 } x.item = null;// 執行 x.item 爲 null size--;// 數據 本身 size -1 modCount++;// 操作 +1 return element;// 返回 remove 的 element }
// remove(Object o) 一般不建議使用,具體是在循環中匹配 然後 執行 unlink 方法 public boolean remove(Object o) { if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) { unlink(x);//注意 return true; } } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) { unlink(x);//注意 return true; } } } return false; } // 注意: 只能remove 第一次匹配到的值 出現重複數據 無法全部remove
-
list.removeAll 方法
// removeAll 方法 採用的是 AbstractCollection 中的方法 public boolean removeAll(Collection<?> c) { Objects.requireNonNull(c);// 判斷需要remove 的數據是否爲null boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) {// 採用迭代器的方式 效率上 優於 arrayList.removeAll 方法 if (c.contains(it.next())) {// 判斷需要remove的數據 it.remove();// 執行remove 操作 modified = true; } } return modified; } // contains 方法 public boolean contains(Object o) { return indexOf(o) != -1; } // indexOf 方法 public int indexOf(Object o) { int index = 0; if (o == null) { for (Node<E> x = first; x != null; x = x.next) { if (x.item == null) return index; index++; } } else { for (Node<E> x = first; x != null; x = x.next) { if (o.equals(x.item)) return index; index++; } } return -1; }
List的實現類LinkedList 各種方法源碼解析
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.