顺序表ArrayList源码分析

ArrayList在添加和删除元素时,会进行扩容操作,扩容通过位运算实现,将容量增加至1.5倍。元素移动使用Arrays.copyOf和System.arraycopy。添加元素涉及索引后所有元素的移动,删除则需将后续元素前移。删除元素推荐使用迭代器,以避免效率低下的直接索引操作。
摘要由CSDN通过智能技术生成

顺序表中的ArrayList源码

  • 新增元素add(int index, E element)的时候,用到了位运算右移一位,此时扩容后的数组大小是原来的1.5倍(n+0.5n=1.5n),代码如下:
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    然后用到了如下代码来将旧的数组中的元素移动到扩容后的数组中去:
    elementData = Arrays.copyOf(elementData, newCapacity);
    然后用到了如下代码来实现,在数组指定索引位置插入元素时,当前索引元素及后面所有元素的移动操作:
    System.arraycopy(elementData, index, elementData, index + 1, size - index);
    最后将添加的元素赋值到指定位置,集合长度加1,代码如下:
    elementData[index] = element;
    size++;
  • 移除元素remove(int index)的时候,将index后面的元素往前移动一位,代码如下:
    System.arraycopy(elementData, index+1, elementData, index, numMoved);
    numMoved表示需要移动的元素个数,计算方式代码如下:
    int numMoved = size - index - 1;
    然后将集合中最后一个元素置为null,同时集合数量减1,代码如下:
    elementData[--size] = null; // clear to let GC do its work

注意: ArrayList在删除集合中的元素的时候要使用到迭代器Iterator,否则会报错,Iterator是ArrayList的父类,代码如下:

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    //这段代码返回值就是集合中的一个元素
    String bean = iterator.next();
    if(bean.equals("tangkun")){
        iterator.remove();
    }
}

面试问题ArrayList

  1. ArrayList大小是如何增加的?
    每一次扩容采用到了位运算右移加上当前容器大小,扩容后大小是原来的1.5倍,并且采用如下代码,将原来的数组中元素拷贝到扩容后的数组中:
    elementData = Arrays.copyOf(elementData, newCapacity);

  2. 什么情况下使用ArrayList
    在集合末尾添加元素,适用于查找和修改操作频繁的情况

  3. 在索引中ArrayList的增加和删除某个对象的过程?效率很低吗?解释一下为什么?
    通过索引增加和删除某个元素,涉及到该元素后面所有元素的移动操作,因此效率很低.
    比如:新增元素索引后面所有的元素移动代码如下:
    System.arraycopy(elementData, index, elementData, index + 1, size - index);
    比如:移除元素索引后面所有的元素移动代码如下:
    System.arraycopy(elementData, index+1, elementData, index, numMoved);

  4. ArrayList如何顺序删除结点?
    采用迭代器Iterator来进行删除,通过iterator对象的hasNext()方法确定要删除元素的索引,然后通过remove()方法来实现删除该索引对应的元素.

  5. ArrayList的遍历方式
    可以用迭代器Iteratornext()方法进行遍历,也可以使用forforeach

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值