顺序表中的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
-
ArrayList大小是如何增加的?
每一次扩容采用到了位运算右移加上当前容器大小,扩容后大小是原来的1.5
倍,并且采用如下代码,将原来的数组中元素拷贝到扩容后的数组中:
elementData = Arrays.copyOf(elementData, newCapacity);
-
什么情况下使用ArrayList
在集合末尾添加元素,适用于查找和修改操作频繁的情况 -
在索引中ArrayList的增加和删除某个对象的过程?效率很低吗?解释一下为什么?
通过索引增加和删除某个元素,涉及到该元素后面所有元素的移动操作,因此效率很低.
比如:新增元素索引后面所有的元素移动代码如下:
System.arraycopy(elementData, index, elementData, index + 1, size - index);
比如:移除元素索引后面所有的元素移动代码如下:
System.arraycopy(elementData, index+1, elementData, index, numMoved);
-
ArrayList如何顺序删除结点?
采用迭代器Iterator
来进行删除,通过iterator
对象的hasNext()
方法确定要删除元素的索引,然后通过remove()
方法来实现删除该索引对应的元素. -
ArrayList的遍历方式
可以用迭代器Iterator
的next()
方法进行遍历,也可以使用for
、foreach