前言
ArrayList与 LinkedList 的最大区别就是底层数据结构
ArrayList:是顺序存储的线性表(普通数组)
LinkedList :是链式存储的线性表(双向链表)
其余各项区别都是由此而生的。
一、增删
ArrayList:使用add(E element)方法,默认尾插,这种情况下时间复杂度为O(1)。
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
如果是指定下标进行插入的话(add(int index, E element)),时间复杂度就为近似于O(N),因为在指定下标插入的时候,第i个和第i个位置之后的(n - i)个元素都要执行向后移的操作。
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++;
}
LinkedList采用链表存储,所以插入删除时间复杂度都不受元素位置的影响,都是近似于O(1)。
二、改查
查:
ArrayList是数组,支持快速随机访问,可以借助下标进行访问。O(1)
LinkedList本质是链表,需要一个节点一个节点的找。O(N)
改:
找到之后改都是常数级的操作,但由于查的时间复杂度不同,这些也不同。
三、空间占用
ArrayList的空间浪费:大多数时候List结尾会留下一部分没有存放数据空间(这是由扩容机制决定的)
LinkedList的空间浪费:链表的节点还需要保存上/下一个节点的地址,节点数据储存率低。
四、拓展
虽然一般面试官聊到ArrayList与 LinkedList 的区别,只是开胃小菜,但不妨碍你自己把他做成大餐。
1.扩容机制
ArrayList的扩容机制,默认容量为10,超出容量直接变为原来的1.5倍,当然还有溢出判断(int),还有大于Integer.MAX_VALUE - 8就直接设为Integer.MAX_VALUE的特殊机制。
详细建议自己了解,毕竟你拓展这一块的核心卖点就是暗示面试官,你自己具有根据源码钻研的意识与能力。
private static final int DEFAULT_CAPACITY = 10;
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和LinkedList都是不同步的,都是线程不安全的。
然后可以聊到解决方案,这部分就可以自由发挥了。
(反正这时你已经掌握了主动权,比如自由发挥时专门挑自己会的讲,但不一次性讲完,吸引面试官继续向下问。)
总结
ArrayList与 LinkedList 的最大区别就是底层数据结构,一个数组一个链表。实际被问到时要学会自然而然拓展。