List,正如它的名字,表明其是有順序的。當討論List的時候,最好拿它跟Set作比較,Set中的元素是無序且唯一;下面是一張類層次結構圖,從這張圖中,我們可以大致了解java集合類的整體架構;
從上面的類層次結構圖中,我們可以發現他們都實現了List接口,它們使用起來非常相似。區別主要在於它們各自的實現,不同的實現導致了不同的性能和不同的操作。
ArrayList是為可變數組實現的,當更多的元素添加到ArrayList的時候,它的大小會動態增大。它的元素可以通過get/set方法直接訪問,因為ArrayList本質上是一個數組。
LinkedList是為雙向鏈表實現的,添加、刪除元素的性能比ArrayList好,但是get/set元素的性能較差。
Vector與ArrayList相似,但是它是同步的。
如果你的程序是線程安全的,ArrayList是一個比較好的選擇。當更多的元素被添加的時候,Vector和ArrayList需要更多的空間。Vector每次擴容會增加一倍的空間,而ArrayList增加50%。
注意: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()); }
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()); }
從以上代碼,我們可以發現它們的使用非常相似,真正地區別在於它們的底層實現和操作復雜度。
Vector和ArrayList幾乎是一樣的,區別在於Vector是線程安全的,因為這個原因,它的性能較ArrayList差。通常情況下,大部分程序員都使用ArrayList,而不是Vector,因為他們可以自己做出明確的同步操作。
表中的add()方法指add(E e), remove()方法指remove(int index)
我使用如下代碼測試它們的性能:
package simplejava; import java.util.ArrayList; import java.util.LinkedList; public class Q24 { public static void main(String[] args) { 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); } }
結果打印如下:
它們性能的區別很明顯。對於Add和remove操作,LinkedList性能較好,但是get操作性能較差。基於上面的時間復雜度表和測試結果,我們可以得出什麼時候使用ArrayList還是LinkedList。簡單的說,LinkedList適用於如下情況:
譯文鏈接:http://www.programcreek.com/2013/03/arraylist-vs-linkedlist-vs-vector/