java-Java 集合 List總結(jié)(LinkedList, ArrayList等使用場景和性能分析)

List概括

先回顧一下List的框架圖

Paste_Image.png
  • List 是一個接口,它繼承于Collection的接口。它代表著有序的隊列。
  • AbstractList 是一個抽象類,它繼承于AbstractCollection。AbstractList實現(xiàn)List接口中除size()、get(int location)之外的函數(shù)。
  • AbstractSequentialList 是一個抽象類,它繼承于AbstractList。AbstractSequentialList 實現(xiàn)了“鏈表中,根據(jù)index索引值操作鏈表的全部函數(shù)”。
  • ArrayList, LinkedList, Vector, Stack是List的4個實現(xiàn)類。
  • ArrayList 是一個數(shù)組隊列,相當于動態(tài)數(shù)組。它由數(shù)組實現(xiàn),隨機訪問效率高,隨機插入、隨機刪除效率低。
  • LinkedList 是一個雙向鏈表。它也可以被當作堆棧、隊列或雙端隊列進行操作。LinkedList隨機訪問效率低,但隨機插入、隨機刪除效率低。
  • Vector 是矢量隊列,和ArrayList一樣,它也是一個動態(tài)數(shù)組,由數(shù)組實現(xiàn)。但是ArrayList是非線程安全的,而Vector是線程安全的。
  • Stack 是棧,它繼承于Vector。它的特性是:先進后出(FILO, First In Last Out)。

第2部分 List使用場景

學東西的最終目的是為了能夠理解、使用它。下面先概括的說明一下各個List的使用場景,后面再分析原因。

如果涉及到“?!?、“隊列”、“鏈表”等操作,應該考慮用List,具體的選擇哪個List,根據(jù)下面的標準來取舍。

  • 對于需要快速插入,刪除元素,應該使用LinkedList。
  • 對于需要快速隨機訪問元素,應該使用ArrayList。
  • 對于“單線程環(huán)境” 或者 “多線程環(huán)境,但List僅僅只會被單個線程操作”,此時應該使用非同步的類(如ArrayList)。
  • 對于“多線程環(huán)境,且List可能同時被多個線程操作”,此時,應該使用同步的類(如Vector)。

通過下面的測試程序,我們來驗證上面的(01)和(02)結(jié)論。參考代碼如下:

import java.util.*;
import java.lang.Class;

/*
 * @desc 對比ArrayList和LinkedList的插入、隨機讀取效率、刪除的效率
 *
 * @author skywang
 */
public class ListCompareTest {

    private static final int COUNT = 100000;

    private static LinkedList linkedList = new LinkedList();
    private static ArrayList arrayList = new ArrayList();
    private static Vector vector = new Vector();
    private static Stack stack = new Stack();

    public static void main(String[] args) {
        // 換行符
        System.out.println();
        // 插入
        insertByPosition(stack) ;
        insertByPosition(vector) ;
        insertByPosition(linkedList) ;
        insertByPosition(arrayList) ;

        // 換行符
        System.out.println();
        // 隨機讀取
        readByPosition(stack);
        readByPosition(vector);
        readByPosition(linkedList);
        readByPosition(arrayList);

        // 換行符
        System.out.println();
        // 刪除 
        deleteByPosition(stack);
        deleteByPosition(vector);
        deleteByPosition(linkedList);
        deleteByPosition(arrayList);
    }

    // 獲取list的名稱
    private static String getListName(List list) {
        if (list instanceof LinkedList) {
            return "LinkedList";
        } else if (list instanceof ArrayList) {
            return "ArrayList";
        } else if (list instanceof Stack) {
            return "Stack";
        } else if (list instanceof Vector) {
            return "Vector";
        } else {
            return "List";
        }
    }

    // 向list的指定位置插入COUNT個元素,并統(tǒng)計時間
    private static void insertByPosition(List list) {
        long startTime = System.currentTimeMillis();

        // 向list的位置0插入COUNT個數(shù)
        for (int i=0; i<COUNT; i++)
            list.add(0, i);

        long endTime = System.currentTimeMillis();
        long interval = endTime - startTime;
        System.out.println(getListName(list) + " : insert "+COUNT+" elements into the 1st position use time:" + interval+" ms");
    }

    // 從list的指定位置刪除COUNT個元素,并統(tǒng)計時間
    private static void deleteByPosition(List list) {
        long startTime = System.currentTimeMillis();

        // 刪除list第一個位置元素
        for (int i=0; i<COUNT; i++)
            list.remove(0);

        long endTime = System.currentTimeMillis();
        long interval = endTime - startTime;
        System.out.println(getListName(list) + " : delete "+COUNT+" elements from the 1st position use time:" + interval+" ms");
    }

    // 根據(jù)position,不斷從list中讀取元素,并統(tǒng)計時間
    private static void readByPosition(List list) {
        long startTime = System.currentTimeMillis();

        // 讀取list元素
        for (int i=0; i<COUNT; i++)
            list.get(i);

        long endTime = System.currentTimeMillis();
        long interval = endTime - startTime;
        System.out.println(getListName(list) + " : read "+COUNT+" elements by position use time:" + interval+" ms");
    }
}

從中,我們可以發(fā)現(xiàn):

  • 插入10萬個元素,LinkedList所花時間最短:29ms。
  • 刪除10萬個元素,LinkedList所花時間最短:15ms。
  • 遍歷10萬個元素,LinkedList所花時間最長:10809 ms;而ArrayList、Stack和Vector則相差不多,都只用了幾秒。

考慮到Vector是支持同步的,而Stack又是繼承于Vector的;因此,得出結(jié)論:

  • 對于需要快速插入,刪除元素,應該使用LinkedList。
  • 對于需要快速隨機訪問元素,應該使用ArrayList。
  • 對于“單線程環(huán)境” 或者 “多線程環(huán)境,但List僅僅只會被單個線程操作”,此時應該使用非同步的類。Vector
  • ArrayList支持序列化,而Vector不支持;即ArrayList有實現(xiàn)java.io.Serializable接口,而Vector沒有實現(xiàn)該接口。
  • Vector支持通過Enumeration去遍歷,而對于需要快速插入,刪除元素,應該使用LinkedList,ArrayList不支持

本文來自: http://www.cnblogs.com/skywang12345/p/3308900.html

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容