ArrayList如何进行的扩容以及数组扩容方式

初始化arraylist请童鞋们自己去百度,我们从添加开始看
点开arraylist的源码,查看add方法,初始化的size进行+1作参
看见没,数组的第++个元素等于参数,懂吧

private int size;
transient Object[] elementData;
public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

点开ensureCapacityInternal方法

transient Object[] elementData;
private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

首先调用了calculateCapacity方法,参数elementData以及我们传递的size+1;
再进入calculateCapacity方法

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
private static final int DEFAULT_CAPACITY = 10;
private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

第一次添加,两个初始化的数组必然相等,那么根据max方法的比较,返回的是DEFAULT_CAPACITY也就是10,因为我minCapacity才第一次,就是个1,下次再来就不相等了
再进入ensureExplicitCapacity方法

protected transient int modCount = 0;
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

第一次比较,肯定不会是大于0的,所以要看的就是当我在calculateCapacity方法中已经大于10的情况下,才会执行grow方法,也就是扩容

private void grow(int minCapacity) {
        // overflow-conscious code
        //拿来老长度
        int oldCapacity = elementData.length;
        //这是新长度,老长度右移一位,代表除以2,newCapacity等于1.5oldCapacity 
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //新长度是否满足要求
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
            //如果新长度还不能满足,那么就进入hugeCapacity方法
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // arrays的方法,原本的数组(elementData),新长度(newCapacity),新的数组产生,包含原数组中的元素
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

hugeCapacity方法

private static int hugeCapacity(int minCapacity) {
//小于0这是出问题了,抛异常
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
            //判断,小于最大的长度,那么就返回integet类型的最大长度,大于就是array的最大长度
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

这样新数组就elementData 就产生了

其实也不是只有Arrays.copyOf这一种,面试被问到了特意查的,面试结果是失败了,没办法,自己菜,没鼓捣过。
System.arraycopy也能行
src:原数组
srcPos:原数组起始位置
dest:目标数组
destPos:目标数组开始位置
length:要复制的元素长度

    public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

这就是建一个新数组,然后吧原来数组的元素通过索引位置以及要复制的长度,给到新索引的开始位置而已。
告辞!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值