原文: ArrayList vs. LinkedList vs. Vector
1,LIst综述
List,正如名字表明的一样,是一个元素有序的序列。说起List,一般会和元素唯一(不重复)但无序的Set进行比较。下图是Collection的类层次图。
2,ArrayList vs. LinkedList vs. Vector
从上图可见,他们都实现自接口List,使用上很相似。背后实现的不同导致了不同操作上效率的不同。
ArrayList的实现是一个可变数组,当有更多元素添加进去,数组大小也会动态增加,其元素可用get、set方法直接访问,因为本质上它就是个数组。
LinkedList的实现是一个双向链表。它在add、remove时比ArrayList快,在get、set时比arrayList慢。
Vector和ArrayList相似,区别是它是同步的(synchronized)。
当线程安全时,ArrayList是更好的选择,Vector和arrayList在元素增加时都需要更多的空间,Vector每次数组大小变成之前的两倍,而ArrayList只增加原来的50%,由于LinkedList还实现了Queue接口,所以有更多的方法,比如offer(),peek(),poll()等。
注意:ArrayList的默认数组大小只有10,比较小,建议在初始化ArrayList时将其数组大小设大一点,这样可以减少变化数组的开销(cost)。
3,ArrayList示例代码
ArrayList<Integer> al = new ArrayList<Integer>();
al.add(3);
al.add(2);
al.add(1);
al.add(4);
al.add(5);
al.add(6);
al.add(6);
Iterator<Integer> iter1 = al.iterator();
while(iter1.hasNext()){
System.out.println(iter1.next());
}
4,LinkedList示例代码
LinkedList<Integer> ll = new LinkedList<Integer>();
ll.add(3);
ll.add(2);
ll.add(1);
ll.add(4);
ll.add(5);
ll.add(6);
ll.add(6);
Iterator<Integer> iter2 = ll.iterator();
while(iter2.hasNext()){
System.out.println(iter2.next());
}
如上所示,使用上几乎一样,区别在于背后的实现和操作上的执行效率
5,Vector
Vector和ArrayList几乎一样,区别是Vector是线程安全的,自身有同步机制。但因为如此,其开销也更大,一般来时,程序员都用ArrayList而不用Vector,当需要同步时可以自己显式的去同步。
6,执行效率对比
测试代码
ArrayList<Integer> arrayList = new ArrayList<Integer>();
LinkedList<Integer> linkedList = new LinkedList<Integer>();
// ArrayList add
long startTime = System.nanoTime();
for (int i = 0; i < 100000; i++) {
arrayList.add(i);
}
long endTime = System.nanoTime();
long duration = endTime - startTime;
System.out.println("ArrayList add: " + duration);
// LinkedList add
startTime = System.nanoTime();
for (int i = 0; i < 100000; i++) {
linkedList.add(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedList add: " + duration);
// ArrayList get
startTime = System.nanoTime();
for (int i = 0; i < 10000; i++) {
arrayList.get(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("ArrayList get: " + duration);
// LinkedList get
startTime = System.nanoTime();
for (int i = 0; i < 10000; i++) {
linkedList.get(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedList get: " + duration);
// ArrayList remove
startTime = System.nanoTime();
for (int i = 9999; i >=0; i--) {
arrayList.remove(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("ArrayList remove: " + duration);
// LinkedList remove
startTime = System.nanoTime();
for (int i = 9999; i >=0; i--) {
linkedList.remove(i);
}
endTime = System.nanoTime();
duration = endTime - startTime;
System.out.println("LinkedList remove: " + duration);
结果是:
ArrayList add: 13265642
LinkedList add: 9550057
ArrayList get: 1543352
LinkedList get: 85085551
ArrayList remove: 199961301
LinkedList remove: 85768810
性能方面的差异是明显的,add、remove时LinkedList更快,但在get时就慢。简单来说,当没有大量数据需要随机访问和有大量add、remove操作时,就选用LinkedList,反之用ArrayList。
--------update 2015.3.22---------
Collection接口有iterator()方法。
List中元素存储顺序和插入顺序是一致的。
当不清楚List的实现时,最好用iterator来遍历其元素,而不要用index,因为可能消耗的时间和index的值大小成比例(java官方文档语)。
-----------------2015.5.10------------
复习。