JCF一 ArrayList、LinkList对比
底层实现:ArrayList底层实现是一个数组,在实例化一个ArrayList的时候,如果没有给定大小,
会默认一个长度为10的数组,ArrayList扩容机制,每当数组内容到达数组的大小的一半的时候
会触发ArrayList的扩容机制扩容后的大小为原先的1.5倍。
LinkList:实现是一个双向链表,每一次添加一个新的元素仅仅需改变一下链表的指向。
List<Integer> arraylist = new ArrayList<Integer>();//基于数组实现
List<Integer> linklist = new ArrayList<Integer>();//基于连表实现
long startTime = System.currentTimeMillis();
for(int i=0;i<200000;i++) {
arraylist.add(i);
}
long endTime1 = System.currentTimeMillis();
for(int i=0;i<200000;i++) {
linklist.add(i);
}
long endTime2 = System.currentTimeMillis();
System.out.println("arraylist add test cost = "+(endTime1-startTime));
System.out.println("linklist add test cost = "+(endTime2-endTime1));
测试结果: 2万次循环
arraylist add test cost = 5
linklist add test cost = 2
20万次循环
arraylist add test cost = 8
linklist add test cost = 7
在数据量比交的小的时候,LinkList的插入速度明显比ArrayList快,逐渐加大数据量大概在20w左右
数据量的时候,ArrayList的速度逐渐追上LinkList并反超,个人认为原因是ArrayList在扩容的扩容
机制影响,统一申请内存空间的效率大于LinkList的效率。LinkList没加入一个节点都需要新建一个
element对象,导致速度变慢。
测试二:每次都在下标为0的地方插入导致每次插入都会把顺序打乱。
List<Integer> arraylist = new ArrayList<Integer>();//基于数组实现
List<Integer> linklist = new LinkedList<Integer>();//基于连表实现
long startTime = System.currentTimeMillis();
for(int i=0;i<20000;i++) {
arraylist.add(0,i);
}
long endTime1 = System.currentTimeMillis();
for(int i=0;i<20000;i++) {
linklist.add(0,i);
}
long endTime2 = System.currentTimeMillis();
System.out.println("arraylist add test cost = "+(endTime1-startTime));
System.out.println("linklist add test cost = "+(endTime2-endTime1));
测试结果一: 2万次
arraylist add test cost = 115
linklist add test cost = 4
测试结果二:5万次
arraylist add test cost = 499
linklist add test cost = 5
每一次arraylist 插入数据的时候都需要将原先的数组进行一次拷贝,导致速度异常的慢而linklist每次插入
仅仅需要修改链表的指向。
在查询的时候arraylist 调用get()方法时直接通过下标寻找时间复杂度为O(1),而linklist虽然同样存在
get()方法,但是通过遍历链表得到的所以时间复杂度为O(n)。
有些理解不到位的地方希望大家给指出谢谢!