ArrayList :
动态的数组, 底层实现是基于数组,所谓的动态就是在增加元素时候判断元素个数是否要超过当前容量,依次判断是否需要扩容。扩容的机制就是:赋值一个原来数组大小的1.5倍的数组空间来存放。
相关源码分析:https://www.cnblogs.com/zhangyinhua/p/7687377.html#_label3_1_3_0
ArrayList的增删改查的操作的复杂度:
add(e) :在尾部直接添加 复杂度 O(1);
add(Index, e): 在某一位置添加 需要将元素移动 时间复杂度 O(n)
remove(e) :元素移动 时间复杂度 O(n)
LinkedList
一种可以在任意位置高效进行插入的有序序列, 基于双向链表实现的。
与ArrayList的时间复杂度的比较
接下来做一些实验来验证一下ArrayList 与LinkedList 在一些操作情况下的效率比较
为了更加精确比较,程序中用了纳秒作为时间单位
实验一:比较LinkedList与ArrayList在尾部插入的时间效率
根据上述理论:在尾部插入两者的时间复杂度都为O(1),那么实际情况如何呢?实验代码如下
public static void showTheTime (int n) {
List<Integer> arrayList = new ArrayList();
List<Integer> linkedList = new LinkedList();
long begin = System.nanoTime();
for(int i = 0; i < n ; i++) {
arrayList.add(i);
}
long end = System.nanoTime();
System.err.println("arrayList尾部插入"+ n +"个元素用时"+(end-begin)+"纳秒");
long begin2 = System.nanoTime();
for(int i = 0; i < n ; i++) {
linkedList.add(i);
}
long end2 = System.nanoTime();
System.err.println("LinkedList尾部插入"+ n +"个元素用时"+(end2-begin2)+"纳秒");
}
实验结果
arrayList尾部插入20000个元素用时3毫秒
LinkedList尾部插入20000个元素用时1毫秒
=================================================
arrayList尾部插入200000个元素用时8毫秒
LinkedList尾部插入200000个元素用时6毫秒
=================================================
arrayList尾部插入250000个元素用时5毫秒
LinkedList尾部插入250000个元素用时40毫秒
=================================================
arrayList尾部插入5000000个元素用时1118毫秒
LinkedList尾部插入5000000个元素用时2888毫秒
=================================================
arrayList尾部插入10000000个元素用时1213毫秒
LinkedList尾部插入10000000个元素用时1933毫秒
=================================================
实验结论 :在数量级别小时,LinkedList的尾部插入效率高,在数量级大时百万级别千万级别时,ArrayList的尾部插入效率高
为什么呢?
这是由于两者的底层实现不同,arraylist 基于数组扩容,而扩容的机制是数组复制为原来的1.5倍。当数据量小时,复制基数小,会进行频繁扩容,而数据量大的时候,由于数组数量基数大,扩容次数会减少。效率逐渐升高。
linkedList 的消耗点在于:每次新增一个元素的时候,都要new一个Node来存储并修改引用。
实验二:ArrayList 与LinkedList在头部添加元素
arrayList头部插入20000个元素用时19毫秒
LinkedList头部插入20000个元素用时3毫秒
=================================================
arrayList头部插入200000个元素用时2160毫秒
LinkedList头部插入200000个元素用时8毫秒
=================================================
arrayList头部插入250000个元素用时3384毫秒
LinkedList头部插入250000个元素用时40毫秒
=================================================
实验结果:显而易见,arrayList遭到了碾压,这也不奇怪 对于arrayList,这是面对了最差的时间复杂度了,所有的元素都要后移,肯定效率不高。而LinkedList在添加元素时候,过程是这样的,先判断元素的位置,如果在前半段,就从前往后找,如果在后半段就从后往前找。对于头部插入,显然是对linkedList有利的。(所以可知 linkedList在中间位置插入元素时候效率最低,因为无论前后查找,此时查找的元素最多)