1. 程式人生 > >比較ArrayList、LinkedList、Vector

比較ArrayList、LinkedList、Vector

翻譯人員: 鐵錨
翻譯時間: 2013年12月2日
原文連結: ArrayList vs. LinkedList vs. Vector

1. List概述

List,就如圖名字所示一樣,是元素的有序列表。當我們討論List時,將其與Set作對比是一個很好的辦法,Set集合中的元素是無序且唯一的。
下圖是Collection的類繼承圖,從圖中你可以對本文所討論的知識有大致的瞭解.
圖1 2. ArrayList、LinkedList與Vector的對比
從圖中可以看出,這三者都實現了List 介面.所有使用方式也很相似,主要區別在於因為實現方式的不同,所以對不同的操作具有不同的效率。
ArrayList 是一個可改變大小的陣列.當更多的元素加入到ArrayList中時,其大小將會動態地增長.內部的元素可以直接通過get與set方法進行訪問,因為ArrayList本質上就是一個數組.
LinkedList
是一個雙鏈表,在新增和刪除元素時具有比ArrayList更好的效能.但在get與set方面弱於ArrayList.
當然,這些對比都是指資料量很大或者操作很頻繁的情況下的對比,如果資料和運算量很小,那麼對比將失去意義.
Vector 和ArrayList類似,但屬於強同步類。如果你的程式本身是執行緒安全的(thread-safe,沒有在多個執行緒之間共享同一個集合/物件),那麼使用ArrayList是更好的選擇。
Vector和ArrayList在更多元素新增進來時會請求更大的空間。Vector每次請求其大小的雙倍空間,而ArrayList每次對size增長50%.
LinkedList 還實現了 Queue
介面,該介面比List提供了更多的方法,包括 offer(),peek(),poll()等.
注意: 預設情況下ArrayList的初始容量非常小,所以如果可以預估資料量的話,分配一個較大的初始值屬於最佳實踐,這樣可以減少調整大小的開銷。
3. ArrayList示例
public static void testArrayList() {
    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示例
public static void testLinkedList() {
    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是同步類(synchronized).因此,開銷就比ArrayList要大.正常情況下,大多數的Java程式設計師使用ArrayList而不是Vector,因為同步完全可以由程式設計師自己來控制。
6. ArrayList與LinkedList效能對比
時間複雜度對比如下:
ArrayList LinkedList
get()  O(1)  O(n)
add()  O(1)  O(1) amortized
remove()  O(n)  O(n)



* 表中的 add() 代表 add(E e),而 remove()代表 remove(int index)'
  • ArrayList 對於隨機位置的add/remove,時間複雜度為 O(n),但是對於列表末尾的新增/刪除操作,時間複雜度是 O(1). 
  • LinkedList對於隨機位置的add/remove,時間複雜度為 O(n),但是對於列表 末尾/開頭 的新增/刪除操作,時間複雜度是 O(1).

我使用下面的程式碼來測試他們的效能:

public static void testPerformance() {
    ArrayList<Integer> arrayList = new ArrayList<Integer>();
    LinkedList<Integer> linkedList = new LinkedList<Integer>();

    int 
    times = 10 * 1000;
    // times = 100 * 1000;
    // times = 1000 * 1000;
    System.out.println("Test times = " + times);
    System.out.println("-------------------------");
    // ArrayList add
    long startTime = System.nanoTime();

    for (int i = 0; i < times; i++) {
        arrayList.add(i);
    }
    long endTime = System.nanoTime();
    long duration = endTime - startTime;
    System.out.println(duration + " <--ArrayList add");

    // LinkedList add
    startTime = System.nanoTime();

    for (int i = 0; i < times; i++) {
        linkedList.add(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println(duration + " <--LinkedList add");
    System.out.println("-------------------------");
    // ArrayList get
    startTime = System.nanoTime();

    for (int i = 0; i < times; i++) {
        arrayList.get(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println(duration + " <--ArrayList get");

    // LinkedList get
    startTime = System.nanoTime();

    for (int i = 0; i < times; i++) {
        linkedList.get(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println(duration + " <--LinkedList get");
    System.out.println("-------------------------");

    // ArrayList remove
    startTime = System.nanoTime();

    for (int i = times - 1; i >= 0; i--) {
        arrayList.remove(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println(duration + " <--ArrayList remove");

    // LinkedList remove
    startTime = System.nanoTime();

    for (int i = times - 1; i >= 0; i--) {
        linkedList.remove(i);
    }
    endTime = System.nanoTime();
    duration = endTime - startTime;
    System.out.println(duration + " <--LinkedList remove");
}
輸出結果如下:
Test times = 10000
-------------------------
1469985 <--ArrayList add
3530491 <--LinkedList add
-------------------------
593678 <--ArrayList get
86914251 <--LinkedList get
-------------------------
625651 <--ArrayList remove
2164320 <--LinkedList remove

Test times = 100000
-------------------------
11480805 <--ArrayList add
26384338 <--LinkedList add
-------------------------
714072 <--ArrayList get
10040809061 <--LinkedList get
-------------------------
1203935 <--ArrayList remove
1595905 <--LinkedList remove

在 1000*1000次的執行中,很長時間過後, LinkedList的get日誌還沒有打印出來,大概是15分鐘左右,結果還是沒有出來.
Test times = 1000000
-------------------------
132632998 <--ArrayList add
322885939 <--LinkedList add
-------------------------
3690752 <--ArrayList get
1520315361147 <--LinkedList get
-------------------------
8750043 <--ArrayList remove
13872885 <--LinkedList remove

他們效能的差異相當明顯,LinkedList在 add和remove 上更快,而在get上更慢(原文是這樣的).

譯者注: 譯者的編譯和執行環境是 MyEclipse的JDK6,不論怎麼看,都是 ArrayList更勝一籌,所以,該怎麼選擇,請根據自己的實際情況來決定,最好自己做測試,因為資料型別不同,JDK版本不同,優化不同,就可能有不同的結果。

根據時間複雜度表格,以及測試結果,我們可以判斷何時該用ArrayList,何時該用LinkedList.

簡單來說,LinkedList更適用於:
  • 沒有大規模的隨機讀取
  • 大量的增加/刪除操作

相關閱讀:

相關推薦

java的list幾種實現方式的效率(ArrayListLinkedListVectorStack),以及 java時間戳的三種獲取方式比較

一、list簡介 List列表類,順序儲存任何物件(順序不變),可重複。 List是繼承於Collection的介面,不能例項化。例項化可以用: ArrayList(實現動態陣列),查詢快(隨

ArrayListLinkedList VectorMap 用法比較

ArrayList和Vector是採用陣列方式儲存資料,此陣列元素總數大於實際儲存的資料個數以便增加和插入元素,二者都允許直接序號索引元素,但是插入資料要移動陣列元素等記憶體操作,所以它們索引資料快、插入資料慢。private transient Object[] eleme

比較ArrayListLinkedListVector

翻譯人員: 鐵錨 翻譯時間: 2013年12月2日 原文連結: ArrayList vs. LinkedList vs. Vector1. List概述 List,就如圖名字所示一樣,是元素的有序列表。當我們討論List時,將其與Set作對比是一個很好的辦法,Set集合中

ArrayListLinkedListVector的對比

最佳實踐 都是 更多 訪問 blog AR 一個數 ali alt 1. List概述 List,就如圖名字所示一樣,是元素的有序列表。當我們討論List時,將其與Set作對比是一個很好的辦法,Set集合中的元素是無序且唯一的。下圖是Collection的類繼承圖,從圖中你

ArrayListLinkedListVector的區別

添加數據 種類型 哈希 取出 精確 索引數據 比較 調用 get Arraylist和Vector是采用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加插入元素,都允許直接序號索引元素,但是插入數據要涉及到數組元素移動等內存操作,所以插入數據慢,查找有下標,所以查詢

Java原始碼分析——java.util工具包解析(一)——ArrayListLinkedListVector類解析

    Java中,List列表類與Set集合類的共同源頭是Collection介面,而Collection的父介面是Iterable介面,在Collection介面下又實現了三個常用的介面以及一個抽象方法,分別為Queue介面、List介面、Se

各種集合框架的總結ArrayListLinkedListVectorHashMapHashTableHashSetLinkedHaSetTreeSetConcurrentHashMap

這幾道Java集合框架面試題在面試中幾乎必問  1.Arraylist 與 LinkedList 異同 1. 執行緒安全: ArrayList 和 LinkedList 都是執行緒不安全的; 2. 資料結構: Arraylist 底層使用的是Object陣列;Linked

HashSetHashMapArrayListLinkedListVector區別

什麼是HashSet HashSet實現了Set介面,它不允許集合中有重複的值,當我們提到HashSet時,第一件事情就是在將物件儲存在HashSet之前,要先確保物件重寫equals()和hashCode()方法,這樣才能比較物件的值是否相等,以確保set中沒有儲存相等的

ArrayListLinkedListVector 分析

ArrayList、LinkedList、Vector 集合對比:   結構 安全 效率 擴容 ArrayList 陣列 不安全 增刪(慢)查詢(快) 1.

ArrayListVectorLinkedList泛型(Generic)

1.ArrayList、Vector、LinkedList ArrayList儲存字串並遍歷 void forEach(Consumer<? super E> action) 執行特定動作的每一個元素的 Iterable直到所有元素都被處理或操作丟擲

Java ArrayListLinkedListVector的使用及效能分析

第1部分 List概括 List 是一個介面,它繼承於Collection的介面。它代表著有序的佇列。 AbstractList 是一個抽象類,它繼承於AbstractCollection。AbstractList實現List介面中除size()、get(int loc

ArrayListLinkedListVector的區別和實現原理

ArrayList、LinkedList、Vector是集合中經常拿來比較和麵試的一個問題,我這裡簡要概括一下他們的區別和實現原理。儲存結構ArrayList和Vector是按照順序將元素儲存(從下表為0開始),刪除元素時,刪除操作完成後,需要使部分元素移位,預設的初始容量都

Java: ArrayListLinkedListVector

ArrayList、LinkedList、Vector都實現了List的介面。 ArrayList List 介面的大小可變陣列的實現。實現了所有可選列表操作,並允許包括 null 在內的所有元素。除了實現 List 介面外,此類還提供一些方法來操作

ArrayListLinkedListVector之間的區別

  ①ArrayList:內部採用陣列儲存元素,支援高效隨機訪問,支援動態調整大小;更適合遍歷查詢,增刪改查的效率相對低; ②LinkedList:內部採用連結串列來儲存元素,支援快速插入/刪除元素,但不支援高效地隨機訪問;更適合增刪改,遍歷效率相對低[無同步];

ArrayListLinkedListVector區別

最近刷面試題,做個隨筆。。。查資料看見下面這圖不錯就偷來了。 一、區別 如圖,三個實現了Java.util.List介面。 Vector和ArrayList底層都是Object[]儲存的

java中ArrayListLinkedListVector的區別

ArrayList、LinkedList和Vector都是實現了List介面。其中,ArrayList和Vector底層是用陣列實現的,因此可以用序號下標來訪問他們,查詢的效率高,一般陣列的大小比要插入的資料大數量要大。LinkedList的底層使用雙向連結串列實現的,因此插

ArrayListLinkedListVector三者的異同

List子介面:儲存有序的、可重複的資料----->“動態”陣列,注意:此處不是真正的動態陣列     **ArrayList:作為List的主要實現類;主要特點有執行緒不安全,但是執行效率高效,底層實現是陣列結構(Collections中定義了synch

List介面與ArrayListLinkedListVector

1.List是集合列表介面,ArrayList和LinkedList都是List介面的實現類,表示一種有序的集合,其中的元素可以重複。 2.ArrayList的動態擴容機制 當ArrayList中增加一個新的物件時,Java會檢查ArrayList確保現有的陣列有足夠的容

14. ArrayListLinkedListVector的區別。

在區分這3個實現類的區別之前,必須清楚的知道集合框架。 集合框架從最高根介面開始分為兩層: collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap

ArrayListLinkedListTreeSet與HashSetHashMap與LinkedHashMap之間的比較

前言:人類一思考,上帝就發笑 之前ArrayList與LinkedList、TreeSet與HashSet、HashMap與LinkedHashMap之間都比較茫然,下面我針對這 幾個類具體類來進行比較,首先我們上一張圖 在上面的比較中,我們針對相同顏色的倆者分別來進行