ArrayList源码分析

执行程序

ArrayList list = new ArrayList();
for (int i = 0; i <= 10 ; i++){
	list.add(i);
}

1.新建空数组

执行ArrayList list = new ArrayList();

//执行ArrayList list = new ArrayList();
public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

2.执行 list.add()

public boolean add(E e) {
    //size 初始值为0;每添加一个元素,size值加1,传到形参minCapacity中
	ensureCapacityInternal(size + 1); //1.进入此方法中,确定是否扩容 
    elementData[size++] = e; //2.然后执行赋值
    return true;
}

2.1  进入到ensureCapacityInternal(): 第一次扩容时,容量为10

private void ensureCapacityInternal(int minCapacity) {
	if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
    //初次进入此方法,minCapacity = 0
    minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); //DEFAULT_CAPACITY = 10
	}

    ensureExplicitCapacity(minCapacity);
}

//ensureExplicitCapacity();
private void ensureExplicitCapacity(int minCapacity) {
    modCount++; // 1.记录集合被修改的次数

    //2.如果elementData的大小不够,就调用grow()扩容
    //添加第11个元素时,11 - 10 > 0 ,进行扩容
    if (minCapacity - elementData.length > 0) //当数组容量小于要添加的数据元素个数时,进行扩容
         grow(minCapacity); //扩容机制,容量不够时,扩容至数组长度的1.5倍
     }

//grow();
//初次传入时,minCapacity = 0
//第一次扩容	newCapacity = 10
//第二次及以后,按照 1.5 倍扩容
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length; //初次创建ArrayList时,存在长度为0的情况
    int newCapacity = oldCapacity + (oldCapacity >> 1); //oldCapacity为0时,newCapacity也为0
    if (newCapacity - minCapacity < 0) //排除newCapacity为0的情况
        newCapacity = minCapacity; //当newCapacity为0时,其被赋给最小容量
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    //生成一个容量为 newCapacity(初次为10,后续扩大1.5倍)的数组
    //将前一个数组的值拷贝到新数组中,elementData重新指向新数组
    elementData = Arrays.copyOf(elementData, newCapacity);
}

 3.从 ensureCapacityInternal()返回,添加数据

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值