[原始碼分析]ArrayList

丶Pz發表於2019-02-22

add

 public boolean add(E e) {
        //先確保陣列容量
        ensureCapacityInternal(size + 1);
        //直接將值放在size位置
        elementData[size++] = e;
        return true;
    }

     private void ensureCapacityInternal(int minCapacity) {
       //如果剛開始為空,並且 容量小於預設容量,則初始化 預設容量 (10)
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        //校驗是否需要擴容
        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        //一定要修改modCount
        modCount++;

        //  當容量大於當前元素條數,需要擴容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

    private void grow(int minCapacity) {
        // 舊容量
        int oldCapacity = elementData.length;
        //新容量 = 舊容量 + 舊容量 * 2;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //如果新容量還是小於需要的容量大小,則採用傳入的minCapacity
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //如果minCapacity太大,還需要修正
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        //最後使用Arrays.copyOf 方法擴容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        //使用 Integer.MAX_VALUE
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

remove

 public E remove(int index) {
        rangeCheck(index);

        modCount++;
        //先獲取該索引位置的值
        E oldValue = elementData(index);
        //找到需要複製的元素個數    a b c d e f (如果要刪除 d,索引是3  6 - 3 -1 = 2)
        int numMoved = size - index - 1;
        //將後邊的元素拷貝到被刪除的索引的位置
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //最後一位置為 null
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

get

 E elementData(int index) {
        return (E) elementData[index];
     }

相關文章