List的實現類LinkedList 各種方法源碼解析

  1. 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;
            }
        }

     

  2. 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;
        }

     

  3. 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 

     

  4. 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;
        }

     

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章