1. 程式人生 > >對比Vector、ArrayList、LinkedList有何區別?

對比Vector、ArrayList、LinkedList有何區別?

Vector

1.執行緒安全的動態陣列

2.如果不需要執行緒安全,並不建議選擇,畢竟同步是有額外開銷的。Vector 內部是使用物件陣列來儲存資料,可以根據需要自動的增加容量,當陣列已滿時,會建立新的陣列,並拷貝原有陣列資料。

3.擴容大小預設為0,可指定每次擴容大小(capacityIncrement變數),當擴容指定大小加上原陣列大小,小於可容下大小時擴大到兩倍,否則判斷是否大於MAX_ARRAY_SIZE。如果大於則擴大到Integer.MAX_VALUE,否則擴大到MAX_ARRAY_SIZE。

注意:這裡Integer.MAX_VALUE,與MAX_ARRAY_SIZE的值為什麼設定這麼大,註釋上有寫是為了防止記憶體溢位。

集合原碼解讀–ArrayList(MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8)

為什麼ArrayList的最大陣列大小是Integer.MAX_VALUE - 8?

 /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    //主要擴容方法,minCapacity最小擴容大小值
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //copy原有陣列值
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

注意:Vector說的是執行緒安全的,他是通過synchronized實現方法同步。其實在有些情況下(複合操作)也不是執行緒安全的參考部落格同步容器(如Vector)並不是所有操作都執行緒安全!:

ArrayList

1.ArrayList 是應用更加廣泛的動態陣列實現,它本身不是執行緒安全的,所以效能要好很多。與 Vector 近似,ArrayList 也是可以根據需要調整容量,不過兩者的調整邏輯有所區別,Vector 在擴容時會提高 1 倍,而 ArrayList 則是增加 50%。

注意和Vector一樣是陣列實現,容器擴大的容量不一樣,但是最大容量一樣

LinkedList

1.雙向連結串列

2.所以它不需要像上面兩種那樣調整容量,它也不是執行緒安全的。

對比:

1.Vector 和 ArrayList 作為動態陣列,其內部元素以陣列形式順序儲存的,所以非常適合隨機訪問的場合。除了尾部插入和刪除元素,往往效能會相對較差,比如我們在中間位置插入一個元素,需要移動後續所有元素。

2. LinkedList 進行節點插入、刪除卻要高效得多,但是隨機訪問效能則要比動態陣列慢。

需要注意的是ArrayList所說的插入、刪除效能相對較差是在非尾部的處理。那麼如果只是在尾部處理那麼效能是沒多大區別的。在平常開發中對自己的資料處理的方式選擇合適的集合類。

Vector 和 ArrayList都是陣列結構,合理制定大小可以有效提高系統性能。在阿里規範中也有說到指定集合大小。

在一些工具中如Arrays.asList()生成的是不可變的集合,需要注意。

可以通過如:Collections.synchronizedList()方法建立執行緒安全的集合。如果效能要求不是很高的情況可使用,畢竟這裡是通過synchronized實現,控制粒度還是很大。