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

 

  1. list.add 方法實現

        //add方法 
        public boolean add(E e) {
            //size: elementData.size 
            ensureCapacityInternal(size + 1);  //判斷數組的大小執行擴容以及copy
            elementData[size++] = e;//執行數組的添加以及size+1
            return true;
        }
        
        //ensureCapacityInternal 方法
        //minCapacity 最小適合的容量
        private void ensureCapacityInternal(int minCapacity) {
            //數組的初始化操作 判斷elementData 和 初始定義的數組是否相等
            //若相等 執行初始化數組容量爲10操作
            if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            //判斷當前數組的容量是否可以容納當前數據的add操作
            ensureExplicitCapacity(minCapacity);
        }
        
        //ensureExplicitCapacity 方法
        private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
    
            //判斷當前最小適合容量是否大於當前elementData的容量大小
            if (minCapacity - elementData.length > 0)//是否需要擴容的核心代碼
                grow(minCapacity);//執行擴容以及copy操作
        }
        
        //grow 方法
        private void grow(int minCapacity) {
            // overflow-conscious code
            int oldCapacity = elementData.length;//定義old容量的大小
            int newCapacity = oldCapacity + (oldCapacity >> 1);//定義new容量的大小 一般爲old容    
                                                               //量的1.5倍
            if (newCapacity - minCapacity < 0)//判斷new容量是否小於最小適合容量
                newCapacity = minCapacity;//將最小適合容量大小賦值爲new容量
            if (newCapacity - MAX_ARRAY_SIZE > 0)//判斷new容量是否大於數組定義的最大size
                newCapacity = hugeCapacity(minCapacity);//判斷當前最小適合容量的大小是否超出數組        
                //定義的最大size 若超出返回 Integer.Max_Value 未超出則返回 MAX_ARRAY_VALUE.
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);//執行新數組的copy操作
        }

     

  2. list.addAll 方法實現

        //addAll 方法
         public boolean addAll(Collection<? extends E> c) {
            Object[] a = c.toArray();//定義Object數組a
            int numNew = a.length;//定義numNew
            ensureCapacityInternal(size + numNew);//add方法中的一致,擴容addAll之後新數組的容量
            System.arraycopy(a, 0, elementData, size, numNew);//執行數組的copy方法
            size += numNew;//定義新的elementData.size
            return numNew != 0;
        }

     

  3. list.remove 方法實現

        //remove int
        E remove(int index);
        
        //remove 實現方法
        public E remove(int index) {
            rangeCheck(index);//檢測當前index是否超出elementData.size,超出拋出異常 
    
            modCount++;
            E oldValue = elementData(index);//查找對應位置的velue 定義爲oldValue
    
            int numMoved = size - index - 1;//定義 移動的位置
            if (numMoved > 0)//判斷當前移動的位置是中間還是末尾
                System.arraycopy(elementData, index+1, elementData, index,
                                 numMoved);//消耗性能的原因 中間數據remove 需要從新定義數組執行copy
            elementData[--size] = null; //末尾的直接設置爲空
    
            return oldValue;
        }
        //remove Object
        boolean remove(Object o);
    
        //實現方法 建議優先選擇remove(int index) 執行remove 操作
        public boolean remove(Object o) {
            if (o == null) {//remove 數據 null 操作
                for (int index = 0; index < size; index++) //循環查找定位 執行remove 方法
                    if (elementData[index] == null) {
                        fastRemove(index);//執行的是remove 方法 
                        return true;
                    }
            } else {//remove 非 null 數據操作
                for (int index = 0; index < size; index++) //循環查找定位 執行remove 方法
                    if (o.equals(elementData[index])) {
                        fastRemove(index);//執行的是remove 方法 請看下面的注意事項
                        return true;
                    }
            }
            return false;
        }
        //注意 remove(Object element)方法只在當前集合中按順序移除一個元素。即使後邊還有 與 element     
        //相同的元素。也不再刪除。若有需求 請選擇 removeAll 方法

     

  4. list.removeAlla方法實現

        //removeAll 方法
        public boolean removeAll(Collection<?> c) {
            Objects.requireNonNull(c);//判斷需要remove的數據是否爲null
            return batchRemove(c, false);//執行removeAll方法
        }
        
        //batchRemove 方法
        private boolean batchRemove(Collection<?> c, boolean complement) {
            final Object[] elementData = this.elementData;//定義一個final 類型的數據
            int r = 0, w = 0;
            boolean modified = false;
            try {
                for (; r < size; r++)//循環比對
                    //查詢當前數組中是否包含需要remove的數據 contains
                    if (c.contains(elementData[r]) == complement)
                        elementData[w++] = elementData[r];
            } finally {
                // Preserve behavioral compatibility with AbstractCollection,
                // even if c.contains() throws.
                if (r != size) {
                    System.arraycopy(elementData, r,
                                     elementData, w,
                                     size - r);
                    w += size - r;
                }
                if (w != size) {
                    // clear to let GC do its work
                    for (int i = w; i < size; i++)
                        elementData[i] = null;
                    modCount += size - w;
                    size = w;
                    modified = true;
                }
            }
            return modified;
        }
    
        //contains 方法 再一次循環了一次elementData[] 性能消耗原因 複雜程度 O(m*n)
        public int indexOf(Object o) {
            if (o == null) {
                for (int i = 0; i < size; i++)
                    if (elementData[i]==null)
                        return i;
            } else {
                for (int i = 0; i < size; i++)
                    if (o.equals(elementData[i]))
                        return i;
            }
            return -1;
        }

     

 

 

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