ArrayList 的添加、移除元素源码分析

1 添加元素

ArrayList 是基于数组存储的,默认数组大小为 10,当添加元素容量不够时,将进行扩容,对于以下代码:

// 创建一个 ArrayList 对象
ArrayList<Integer> nums = new ArrayList<>();
// 向集合中添加元素
nums.add(1);
nums.add(2);
nums.add(3);

当执行 new ArrayList() 时,调用 ArrayList 无参的构造方法

public ArrayList() {
    // DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是一个空的 Object 类型的数组,当添加第一个元素时,elementData 指向一个大小为 10 的数组
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

当调用 add() 方法时

public boolean add(E e) {
    // 当前元素个数+1,判断是否需要进行扩容操作
    ensureCapacityInternal(size + 1);
    // 将此元素添加到数组
    elementData[size++] = e;
    return true;
}

ensureCapacityInternal 方法

 private void ensureCapacityInternal(int minCapacity) {
     // 当第一次添加元素,条件成立
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        // 取最大值,DEFAULT_CAPACITY 的值为 10,minCapacity 第一次添加元素传入 1
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}

ensureExplicitCapacity 方法

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

   // 当容量不够时,进行扩容
   if (minCapacity - elementData.length > 0)
       grow(minCapacity);
}

grow 方法

private void grow(int minCapacity) {
    // 当前数组长度
    int oldCapacity = elementData.length;
    // 新的数组长度 = 当前数组长度 + (当前数组长度右移 1 位),第一次添加 newCapacity = 0
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    // 第一次添加元素,条件成立 0 - 10 < 0,赋值 newCapacity = 10,因此,调用无参构造方法默认数组大小为 10
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // 调用 copyOf 方法,创建新的大小为 newCapacity 的数组,并将原来数组的元素拷贝到新数组
    elementData = Arrays.copyOf(elementData, newCapacity);
}

2 删除元素

// 移除指定索引的元素
nums.remove(1);

remove 方法

public E remove(int index) {
    // 检测指定的索引是否越界
    rangeCheck(index);

    modCount++;
    // 获取待移除的元素,操作完成后返回
    E oldValue = elementData(index);

    // 计算出 index 之后元素的个数
    int numMoved = size - index - 1;
    if (numMoved > 0)
        // 调用 arraycopy 方法将 index 之后的元素向前移动一位,将 index 位置的元素覆盖掉
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    // 将数组最后位置的值置为 null
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值