-
底层数据结构:ArrayList 底层是 Object 数组,LinkedList 底层是 双向链表(1.6以前是循环链表)
-
时间复杂度对比:
Algorithm | ArrayList | LinkedList |
---|---|---|
seek front | O(1) | O(1) |
seek back | O(1) | O(1) |
seek to index | O(1) | O(N) |
insert at front | O(N) | O(1) |
insert at back | O(1) | O(1) |
insert after an item | O(N) | O(1) |
remove front | O(N) | O(1) |
remove back | O(1) | O(1) |
remove by index | O(N) | O(N) |
remove by object | O(N) = O(2N) | O(N) |
PS: 时间上还需要注意一点,ArrayList 如果前期没有定义好长度的话(初始容量是10,jdk1.4~1.8),后面插入数据时,会花费一定的时间进行扩容,每次扩容的大小为原大小的1.5倍。(经过测试,长度在20W以下时,LinkedList 插入速度会小于等于 ArrayList 超过50W时,LinkedList 就会 慢慢大于ArrayList了,可能跟内存分配有关)
ensureCapacity:该方法的作用是预先设置Arraylist的大小,这样可以大大提高初始化速度。
-
空间上:ArrayList 基本上只需要存储元素数组,而LinkedList 除了元素本身之外,还需要存储前驱和后继的指针(地址)。
-
什么时候选择 LinkedList ,而不是 ArrayList ?
绝大多数情况下,其实使用 ArrayList 就行了,LinkedList 适用于使用频繁的中间插入和删除,尤其是在有迭代器的情况下插入删除。
LinkedList 缺点:
- 内存分配是分散的,可能游离在各个片区,影响整体性能,不利于 缓存局部性
- 内存占用大
ArrayList 缺点:
巨型数组(例如:10G)操作时,中间插入、删除 速度慢,扩容,会导致 GC频繁等问题;但是一般应该不会这么大,一般都会放到数据库存储处理。