ArrayList add方法深度解析。

ArrayList提供了四个方法添加元素,前两种添加一个元素,后两种为添加一Collection。

第一种我们前面已经见过并且分析过。我们看一下下面的图解以及代码

public boolean add(E e) {
        //确保数组长度,不够则扩展
        ensureCapacityInternal(size + 1); 
        //添加元素
        elementData[size++] = e;
        return true;
    }

第二种是在指定的位置添加一个元素。System.arraycopy(elementData, index, elementData, index + 1,
size - index);这方法很重要,list元素的添加很大程度上都依赖这个方法。第一个参数为要复制的源数组,第二个参数为要复制的开始位置,第三个是要复制的目的数组,第四个参数是复制到目的数组的开始位置,第五个参数为要复制的长度。

public void add(int index, E element) {
        //检查插入索引位置,超出范围,抛出异常,跟List长度作比较
        rangeCheckForAdd(index);
        //根据情况扩展数组长度,如果扩展数组长度,进行一次数组的复制
        ensureCapacityInternal(size + 1);  
        //赋值新数组
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        //添加元素
        elementData[index] = element;
        //list长度加1
        size++;
    }

private void rangeCheckForAdd(int index) {
         //如果索引大于List长度或者小于0,抛出异常
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

第三个方法是添加一个集合

public boolean addAll(Collection<? extends E> c) {
        //转换为数组
        Object[] a = c.toArray();
        int numNew = a.length;
        //确保数组长度足够存储
        ensureCapacityInternal(size + numNew);  
        //直接将转换后的数组从索引0开始复制
        //复制到elementData,从size开始复制
        //复制长度为a的长度,即集合长度
        System.arraycopy(a, 0, elementData, size, numNew);
        //list长度增加
        size += numNew;
        //如果要添加的集合长度为0,添加失败,即没添加
        return numNew != 0;
    }

第四个方法是在指定的位置添加一个集合,在指定的位置添加一个集合,则至少要对数组进行两次的复制,第一次移动元素,一遍有足够的空间添加集合,第二次才是添加集合,并且都是用System.arrayCopy()进行数组的处理。

public boolean addAll(int index, Collection<? extends E> c) {
        //也要检查索引是否越界
        rangeCheckForAdd(index);
        //转换为数组
        Object[] a = c.toArray();
        int numNew = a.length;
        //确保数组长度足够
        ensureCapacityInternal(size + numNew);
        //要移动的元素个数
        int numMoved = size - index;
        if (numMoved > 0)
           //移动元素
            System.arraycopy(elementData, index, elementData, index + numNew,
                             numMoved);
        //添加集合
        System.arraycopy(a, 0, elementData, index, numNew);
        //长度增加
        size += numNew;
        return numNew != 0;
    }

后续我们自己实现一个自己的List。

转载于:https://my.oschina.net/jettyWang/blog/909877

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值