首先看一个面试题
ArrayList和LinkedList的区别?
通过观看ArrayList的源码,ArrayList是对数组Array的一个封装。
ArrayList中的add原理:
//添加
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!! 总容量+1
elementData[size++] = e; //末尾位置赋值
return true;
}
transient Object[] elementData; //ArrayList中定义,存放List中的数据
//插入
public void add(int index, E element) {
rangeCheckForAdd(index); //判断索引是否越界
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index); //复制后面的数据,到一个新数组中
elementData[index] = element; //赋值
size++;
}
//所以ArrayList因为每次插入一个元素,就要执行一次arrayCopy操作,复制到一个新数组中去了
在看下一段代码
public static void main(String[] args) {
int[] n = {1,2,3,4};
int[] m = new int[4];
System.arraycopy(n,2,m,0,2);
for (int i : m) {
System.out.print(i+" ");
}
}
输出结果为:
这里可以明白,arraycopy的作用就是将原数组中的一部分复制到一个新的数组中去
因为ArrayList也是对Array的一个封装,底层实现其实也是数组。这里把原数组在插入位置截成2部分,
前面部分扩容一位,并执行赋值操作。后1部分执行arraycopy()方法,其实是将后半部分的数组复制给了一个新的数组,刚好这个新数组就是原来的数组位置向后移了1位。(作用上看起来是将插入节点之后的数组数据整体向后移了一位。)
正是因为每次插入一个数组,都要执行一次arraycopy操作,挪动数组导致的开销很大。所以ArrayList的增删改效率都是低于LinkedList的。