http://www.programcreek.com/2013/03/arraylist-vs-linkedlist-vs-vector/
1.List总览
List,顾名思义,是一个有序序列。当我们讨论List时,会和Set进行比较,Set是一堆无序且唯一的元素集合。下面是接口Collection的类的层级图。你可以从中对于Java Collections有总体的了解。
2.ArrayList vs. LinkedList vs.Vector
从层级图看出,他们都实现了List接口。他们使用方式相似。他们的主要区别在于实现方式,这会导致每个操作表现的性能不同。
ArrayList 被实现成为一个可变长数组,它的尺寸随着元素添加而动态增长。它的元素可被直接访问,使用get和set方法。ArrayList 本质上就是一个数组。
LinkedList 被实现成为一个双链表。它在增删操作的性能上优于ArrayList,但是在get和set方法劣于ArrayList。
Vector 与ArrayList相似,但它是同步的。
如果你的程序是线程安全的那么ArrayList是更好的选择。Vector和ArrayList 随元素逐渐增加需要更多的空间。Vector 每次增长为它的数组尺寸的两倍,而ArrayList 每次只增长50%。LinkedList优于还实现了Queue接口,因此有更多的方法,如offer(),peek(),poll(),etc.
注意:ArrayList的初始容量非常小,给ArrayList一个相对大的初始容量是一个好习惯,这能避免从定义大小的开销
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开销大,大部分程序员都使用ArrayList代替Vector,他们自己可以显式地同步。
6.ArrayList vs. LinkedList 性能
时间复杂度比较如下:
*add()表示add(E e),remove()代表remove(int index)
用以下例码测试他们的性能
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
The difference of their performance is obvious. LinkedList is faster in add and remove, but slower in get. Based on the complexity table and testing results, we can figure out when to use ArrayList or LinkedList. In brief, LinkedList should be preferred if:
there are no large number of random access of element
there are a large number of add/remove operations