说明:
本笔记是对http://pengcqu.iteye.com/blog/502676这篇帖子学习的总结与拓展
先看博主结论:
1.对ArrayList和LinkedList而言,在列表末尾增加一个元素所花的开销都是固定的。对ArrayList而言,主要是在内部数组中增加一项,指向所添加的元素,偶尔可能会导致对数组重新进行分配;而对LinkedList而言,这个开销是统一的,分配一个内部Entry对象。
2.在ArrayList的中间插入或删除一个元素意味着这个列表中剩余的元素都会被移动;而在LinkedList的中间插入或删除一个元素的开销是固定的。
3.LinkedList不支持高效的随机元素访问。
4.ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
然而博主不全是对的,根据6楼的回复代码测试发现,linkedList不是中间插入开销少,可是头插入的开销小,LinkedList在队列末尾增加元素的花销并不是固定的,只有在头部插入的花销非常小而且稳定。
测试代码(转载)如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class ArrayOrLinked {
static List<Integer> array=new ArrayList<Integer>();
static List<Integer> linked=new LinkedList<Integer>();
public static void main(String[] args) {
for(int i=0;i<10000;i++){
array.add(i);
linked.add(i);
}
System.out.println("array time:"+getTime(array));
System.out.println("linked time:"+getTime(linked));
System.out.println("array insert time:"+insertTime(array));
System.out.println("linked insert time:"+insertTime(linked));
}
public static long getTime(List list){
long time=System.currentTimeMillis();
for(int i=0;i<10000;i++){
int index=Collections.binarySearch(list, list.get(i));
if(index!=i){
System.out.println("ERROR!");
}
}
return System.currentTimeMillis()-time;
}
public static long insertTime(List list){
long time=System.currentTimeMillis();
for(int i=100;i<10000;i++){
list.add(100,i);
}
return System.currentTimeMillis()-time;
}
}
...
个人的结论:
1.对ArrayList的遍历查询速度比LinkedList快的多。
2.在ArrayList的中间插入速度不管是插入哪个位置都较为平均,速度快慢要视List集合的大小。
3 . LinkedList的头部插入或删除一个元素的开销是固定的,所以在集合较大又需要频繁插入数据的场景适合使用LinkedList。
小拓展:
看过源码的人会发现:
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
… java
ArrayList 和 LinkedList 都实现了 List接口,可克隆和序列化
区别是:
ArrayList 继承了AbstractList 实现了 RandomAccess
LinkedList 继承了AbstractSequentialList 实现了 Deque
再看测试中用到的binarySearch方法
public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
else
return Collections.iteratorBinarySearch(list, key);
}
可以看到,list在实现了RandomAccess和没有实现RandomAccess的情况走的是不一样的方法,这也是导致ArrayList和LinkedList的测试结果不同的主要原因。