当有人问你ArrayList与LinkedList的区别时, 一般的回答都是:
ArrayList是数组结构, 插入和查找比较快; LinkedList是双向链表结构, 删除比较快;
但这样的回答, 只能算是及格, 需要细化更多点再回答才行.
1.ArrayList是数组结构, 插入效率很高;
但确定好初始容量之后, 性能会更高.
在使用无参构造函数初始化时, 内部只会创建一个空数组;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}在添加元素时, 会进行容量计算和扩容等操作, 性能自然也就被拖下来了.
具体操作:
1.容量计算
2.申请新数组空间
3.数组拷贝
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}2.ArrayList修改节点时,时间复杂度是O(1), 性能非常高.
3.ArrayList删除节点时, 会涉及到后续元素的迁移, 存在数组拷贝操作, 性能也就很差, 时间复杂度看起来是O(1), 其实是O(N).
System.arraycopy(elementData, index+1, elementData, index, numMoved);4. LinkedList是双向链表, 在头部和尾部插入, 修改和删除时, 时间复杂度是O(1);
其他节点操作时, 因为元素的遍历查找, 时间复杂度是O(N).
注意: LinkedList这里的O(N)会比ArrayList中O(N)性能慢, 是因为LinkedList遍历时需要到内存中查找, 而ArrayList中的数据会有一部分或者全部进入CPU缓存中, 性能也就高了很多.
5. 遍历时, ArrayList使用索引遍历; LinkedList使用迭代器遍历;