顺序表ArrayList源码分析

顺序表中的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 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

你可能感兴趣的:(Java基础,面试,java,ArrayList)