ArrayList源码分析

ArrayList

可扩容数组原理的List实现类,实现类所有的List接口方法,并且允许插入null。Java语言中最常用的集合类。

源码分析
  1. ArrayList元素实际上保存在一个名字为elementData的Objec类型的数组内
  2. 无参构造器实例化时,elementData为{},默认的容量为10
  3. 第一次添加元素时,会先扩容
public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));   //先计算要扩容到容量值
}

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  //如果通过无参构造器实例化的,
    //第一次添加元素时,
    //判断成立,直接返回默认容量10,
    //如果是通过有参构造器实例化的或者不是第一次添加元素,这里会直接返回传入的需要扩容的值,和默认容量值无关
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;  
}

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)  //扩容值超过数组长度,扩容
        grow(minCapacity);
}

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);  //数组长度增大1.5倍
    if (newCapacity - minCapacity < 0)  //1.5倍增大后依然小于目标扩容值,直接按目标值扩容
        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);  //扩容
}
总结
  • 如果使用无参构造器实例化的,添加第0个元素时,会直接走扩容流程,实例化一个长度为10的数组替换原有的elementData对象,继续添加第1-9个元素时,不会触发扩容,直到添加第10个元素时,开始扩容,实例化一个长度为15的数组替换原来elementData对象,往后,以此类推。。。
  • 如果是使用的不是无参构造器实例化的,实例化时elementData对象就会有长度,假设实例化的长度为4,当添加第0-3个元素时,不会触发扩容,直到添加第4个元素时,才会将容量扩大为6,然后以此类推。。。
  • 源码内部没有任何同步机制,所以ArrayList不是线程安全的
  • 底层容器是数组,所以添加删除元素效率低,随机查询效率高,因为直接通过数组下标访问
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值