Java集合 03.深入ArrayList源码

Java集合框架 03.深入ArrayList源码

前置知识

数据结构

  • 数组

java

  • 数组

正文

  ArrayList是基于动态数组实现的,对象内部存在一个Object数组elementData。

transient Object[] elementData;
  1. 可以随机访问,按照索引位置进行访问效率很高,用算法描述中的术语,效率是O(1)。
  2. 除非数组已排序,否则按照内容查找元素效率比较低,具体是O(N), N为数组内容长度,也就是说,性能与数组长度成正比。
  3. 添加元素的效率还可以,重新分配和复制数组的开销被平摊了,具体来说,添加N个元素的效率为O(N)。
  4. 插入和删除元素的效率比较低,因为需要移动元素,具体为O(N)。
elementData初始化与扩容

  ArrayList在新增元素的时候,会判断elementData数组大小是否能存下。这个方法便是void ensureCapacityInternal(int minCapacity)

public boolean add(E e) {
    ensureCapacityInternal(size + 1); 
    elementData[size++] = e;
    return true;
}

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

private static int calculateCapacity(Object[] elementData, int minCapacity) {
    //判断elementData == {},等价于判断ArrayList实例是否未初始化。
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        //确保初始化长度最小为10。
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
    
private void ensureExplicitCapacity(int minCapacity) {
    //修改计数+1,相关知识见Iterable。
    modCount++;

    if (minCapacity - elementData.length > 0)
            grow(minCapacity);
}

  java7中elementData默认会初始化为长度为10的数组。java8中做了修改,只有在第一次插入的时候才会进行实际的初始化。

private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    //1.5倍扩容
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    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);
}

  扩容函数中的核心就是进行1.5倍扩容elementData数组。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值