新增元素
从头部插入
ArrayList从集合头部位置新增元素花费的时间595
LinkedList从集合头部位置新增元素花费的时间15
涉及到数组复制
从中间插入
ArrayList从集合中间位置新增元素花费的时间1
LinkedList从集合中间位置新增元素花费的时间101
从尾部插入
ArrayList从集合尾部位置新增元素花费的时间69
LinkedList从集合尾部位置新增元素花费的时间193
ArrayList 在添加元素的时候如果不涉及到扩容,性能在两种情况下(中间位置新增元素、尾部新增元素)比 LinkedList 好很多,只有头部新增元素的时候比 LinkedList 差,因为数组复制的原因。
当然了,如果涉及到数组扩容的话,ArrayList 的性能就没那么可观了,因为扩容的时候也要复制数组
删除元素
ArrayList
ArrayList 删除元素的时候,有两种方式,一种是直接删除元素(remove(Object)),需要直先遍历数组,找到元素对应的索引;一种是按照索引删除元素(remove(int))
但从本质上讲,都是一样的,因为它们最后调用的都是 **fastRemove(Object, int)** 方法
从源码可以看得出,只要删除的不是最后一个元素,都需要数组重组。删除的元素位置越靠前,代价就越大
LinkedList
LinkedList 删除元素的时候,有四种常用的方式:
**remove(int)**,删除指定位置上的元素
先检查索引,再调用 node(int) 方法( 前后半段遍历,和新增元素操作一样)找到节点 Node,然后调用 unlink(Node) 解除节点的前后引用,同时更新前节点的后引用和后节点的前引用
**remove(Object)**,直接删除元素
也是先前后半段遍历,找到要删除的元素后调用 unlink(Node)。
**removeFirst()**,删除第一个节点
删除第一个节点就不需要遍历了,只需要把第二个节点更新为第一个节点即可
**removeLast()**,删除最后一个节点
删除最后一个节点和删除第一个节点类似,只需要把倒数第二个节点更新为最后一个节点即可
可以看得出,LinkedList 在删除比较靠前和比较靠后的元素时,非常高效,但如果删除的是中间位置的元素,效率就比较低了
从集合头部删除元素时,ArrayList 花费的时间比 LinkedList 多很多;
ArrayList从集合头部位置删除元素花费的时间380
LinkedList从集合头部位置删除元素花费的时间4
从集合中间位置删除元素时,ArrayList 花费的时间比 LinkedList 少很多;
ArrayList从集合中间位置删除元素花费的时间381
LinkedList从集合中间位置删除元素花费的时间5922
从集合尾部删除元素时,ArrayList 花费的时间比 LinkedList 少一点。
ArrayList从集合尾部位置删除元素花费的时间8
LinkedList从集合尾部位置删除元素花费的时间12
遍历 LinkedList 的时候,千万不要使用 for 循环,要使用迭代器。
也就是说,for 循环遍历的时候,ArrayList 花费的时间远小于 LinkedList;迭代器遍历的时候,两者性能差不多
LinkedList用for循环遍历性能差的原因 : 因为每一次外层的 for 循环,都要执行一次 node(int) 方法进行前后半段的遍历
迭代器只会调用一次 **node(int)** 方法,在执行 list.iterator() 的时候:先调用 AbstractSequentialList 类的 iterator() 方法,再调用 AbstractList 类的 listIterator() 方法,再调用 LinkedList 类的 listIterator(int) 方法