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/