ArrayList部分源码了解(扩容、删除)--个人理解

ArrayList部分源码解释(扩容、删除)

扩容

    ArrayList<Integer> list=new ArrayList<>();
    int i=0;
    while (i<=9){
    list.add(i++);
    }
    list.add(2);

1、第一行进入构造函数(无参)

//有参构造函数,除了负数,initialCapacity多大就开辟多大的空间
public ArrayList(int initialCapacity) {
    if (initialCapacity > 0) {//自定义容量不为0,如new ArrayList<>(11);
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) {//自定义容量为0,如new ArrayList<>(0);
        this.elementData = EMPTY_ELEMENTDATA;//传值为0
    } else {
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}
//无参构造函数
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//对象实例化后list集合还是一个空集合
}

2、第四行进入添加元素(模拟第一次add操作,可知第一次添加操作后才会给集合一个10的容量)

public boolean add(E e) {
    ensureCapacityInternal(size + 1); //1
    elementData[size++] = e;//这里说明list集合的add方法就是往elementData数组中放元素
    return true;
}
private void ensureCapacityInternal(int minCapacity) {//确定内部容量
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));//第一次此时minCapacity为10
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {//计算容量
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//判断当前elementData数组是否时null,如果是就将当前数组容量和默认容量10比较,一般第一次进来之后都会变成10
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
private void ensureExplicitCapacity(int minCapacity) {//确保明确的容量
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)//当前所需容量minCapacity比实际容量大,必须进行扩容
        grow(minCapacity);
}
private void grow(int minCapacity) {//扩容开始
    // overflow-conscious code
    int oldCapacity = elementData.length;//老数组为当前数组容量,第一次添加则为0
    int newCapacity = oldCapacity + (oldCapacity >> 1);//进行1.5倍扩容,如果是第一次,newCapacity执行完为0
    if (newCapacity - minCapacity < 0)//准备扩容的值没有实际所需的容量大,就把实际需要的容量设置为扩容值
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)//这里是看当前所需容量是否超过数组最大的容量,一般不会超过
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);//*** 这里是扩容的重点!!!!
}
当list集合是使用无参构造后第一次添加元素,先进入ensureCapacityInternal,此时minCapacity=1,进入后调用calculateCapacity方法,如果底层数组elementData是null,就把minCapacity和DEFAULT_CAPACITY(10)比较,比较完后minCapacity=10返回
进入ensureExplicitCapacity方法判断当前数组所需容量minCapacity是否大于实际容量,大于时进行扩容

3、第一次扩容完后,底层数组容量为10,第6行为添加10个元素后,现在模拟添加第11个元素

public boolean add(E e) {
    ensureCapacityInternal(size + 1); //11
    elementData[size++] = e;
    return true;
}
private void ensureCapacityInternal(int minCapacity) {//确定内部容量,minCapacity=11
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {//计算容量
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {//第11次elementData为10,进不来
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;//直接返回minCapacity=11
}
private void ensureExplicitCapacity(int minCapacity) {//确保明确的容量
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0)//当前所需容量minCapacity(11)比实际容量10大,必须进行扩容
        grow(minCapacity);
}
private void grow(int minCapacity) {//扩容开始
    // overflow-conscious code
    int oldCapacity = elementData.length;//老数组为当前数组容量,第11次oldCapacity为10
    int newCapacity = oldCapacity + (oldCapacity >> 1);//进行1.5倍扩容,扩容完之后newCapacity为15
    if (newCapacity - minCapacity < 0)//准备扩容的值newCapacity比实际所需minCapacity的容量大,直接跳过
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)//这里是看当前所需容量是否超过数组最大的容量,一般不会超过
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);//*** 这里是扩容的重点!!!!
}

remover 删除

下标删除

//删除原理:数组复制
public E remove(int index) {
        rangeCheck(index);//判断是否越界

        modCount++;//统计修改次数
        E oldValue = elementData(index);//保存下要删除的元素

        int numMoved = size - index - 1;//统计要移动的元素个数
        if (numMoved > 0)//数组元素前移
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;//返回删除的值
    }

元素删除

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {//删除元素和列表的元素进行equals比较
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
posted @ 2021-02-21 20:43  平流层  阅读(83)  评论(0)    收藏  举报