ArrayList.add方法底层浅析

java ArrayList.add方法一共有两种方式,如下代码:

ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);//第一种,顺序在末尾添加元素
arr.add(0,2);//第二种,在指定位置添加元素
System.out.println(arr);

第一种是添加在末尾,第二种是添加在指定位置

我们分别来看下这两种方法底层是怎么实现的


第一种:

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

第一种方式十分的简单,先用ensureCapacityInternal()方法增加list长度实现,然后把新的元素放到末尾


第二种:

public void add(int index, E element) {
    rangeCheckForAdd(index);//检查index合法性

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}

第二种方式先用rangeCheckForAdd()方法查看的index的合法性,大于list.size的和小于0,则会报错数组越界,代码如下

private void rangeCheckForAdd(int index) {
    if (index > size || index < 0)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

判断完index的合法性之后,然后用ensureCapacityInternal()方法扩容

之后使用System.arraycopy()方法对list进行操作

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

src:源数组(被操作的数组);

srcPos:源数组要复制的起始位置(从源数组的什么位置开始复制);

dest:目的数组(要复制到的那个数组);

destPos:目的数组放置的起始位置(从哪个元素开始覆盖);

length:复制的长度(复制多少位);

//例:
//数组1:
int[] arr1 = { 1, 2, 3, 4, 5 };
//数组2:
int[] arr2 = { 6, 7, 8, 9, 10 };
//运行:
System.arraycopy(arr, 1, arr2, 0, 2);

意思就是复制arr1的下标1位置开始往后的两个元素[2, 3],然后替换arr2中的下标0位置开始,往后的两个元素[6, 7],最后运行的的结果是:{2,3,8,9,10}

这个方法同样可以实现自己到自己的拷贝,也就是ArrayList.add往中间插入的方法用到的用法

//例:
//数组: //ArrayList.add方法中先用ensureCapacityInternal进行了扩容,使得末尾空出一个null
object[] arr = { 1, 2, 3, 4, 5 ,6 ,7 ,8 ,null};
System.arraycopy(arr, 1, arr, 2, 7);
//这段代码的执行的结果为:{ 1,null, 2, 3, 4, 5 ,6 ,7 ,8};

这时候我们再来看下ArrayList.add方法,就十分的清晰了

public void add(int index, E element) {
    rangeCheckForAdd(index);//检查index合法性

    ensureCapacityInternal(size + 1);  // 扩容
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);//把index位置空出来,给插入的元素留位置,后边的元素向后顺延一个
    elementData[index] = element;//在空位添加元素
    size++;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值