1. 程式人生 > >原始碼淺析 ArrayList、Vector、LinkedList 的區別

原始碼淺析 ArrayList、Vector、LinkedList 的區別

從類的定義淺析

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public class Vector<E>
    extends AbstractList<E>
    implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public
class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable public abstract class AbstractSequentialList<E> extends AbstractList<E> {
首先從繼承父類來看:

ArrayList & Vector 都繼承了AbstractList 抽象類(提供了
List 介面的預設

實現,支援隨機訪問);
LinkedList 繼承了 AbstractSequentialList(提供了
List 介面的簡化實現,簡化在只支援按次序訪問);

其次從實現介面來看:

①、三者都實現了 List 介面(定義了列表必須實現的方法)、Cloneable 介面(可以呼叫Object.clone方法返回該物件的淺拷貝)、java.io.Serializable 介面(支援序列化和反序列化);
②、ArrayList & Vector 兩者都實現了 RandomAccess 介面(提供了快速隨機訪問儲存的元素的功能),而 LinkedList 實現了 Deque 介面(支援雙向佇列

從類的屬性淺析

ArrayList.java

    private static final int DEFAULT_CAPACITY = 10; // 預設容量
    transient Object[] elementData;                 // 裝元素的容器,不可序列化
    private int size;                               // ArrayList 的大小

Vector.java

    protected Object[] elementData;   // 裝元素的容器
    protected int elementCount;       // Vector 的大小
    protected int capacityIncrement;  // 每次 Vector 容量增加時的增量值

LinkedList.java

    transient int size = 0;     // LinkedList 的大小
    transient Node<E> first;    // 頭指標
    transient Node<E> last;     // 尾指標
    // 結點的定義
    private static class Node<E> {
        E item;       // 結點值
        Node<E> next; // 下一個結點
        Node<E> prev; // 前一個結點
        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

由上原始碼可知:
①、ArrayList & Vector 兩者底層的資料結構是陣列結構,所以改查很快,增刪較慢(又因為 Vector執行緒同步的,所以增刪改查都比 ArrayList 慢)。而 LinkedList 的底層的資料結構是連結串列結構,所以改查較慢,增刪較快
②、ArrayList & Vector 底層都維護了一個 Object[] 物件陣列用於儲存物件,預設陣列的長度是 10。但是 ArrayList 的物件陣列,通過 transient 修飾,不可序列化
③、Vector 維護了一個 capacityIncrement 欄位,可以通過構造器去設定每次擴容的大小,而 ArrayList 沒有。

從類的擴容方法淺析

ArrayList.java

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 擴容
        elementData[size++] = e;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        // 陣列擴容:增大 0.5 倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

Vector.java

    public synchronized boolean add(E e) {
        modCount++;
        // 擴容方法
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    private void ensureCapacityHelper(int minCapacity) {
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        // 陣列擴容:增大 1 倍(capacityIncrement  表示每次 Vector 容量增加時的增量值)
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

由上原始碼可知:
ArrayList 擴容時,容量自動增長為原來的容量的 1.5 倍,而 Vector 的容量自動增長為原來的容量的 2 倍

從遍歷的方法淺析

三者都支援三種遍歷方式:for-each()(幾乎與迭代器一樣)、迭代器方式下標遞增或遞減迴圈
ArrayList下標遞增或遞減迴圈方式是速度最快的,但是 for-each() 實現更加簡單,且速度沒慢太多,推薦使用。
LinkedListfor-each() 方式是速度最快的。

總結

①、
ArrayList & Vector 支援隨機訪問
LinkedList 只支援按次序訪問

②、
三者都定義了列表必須實現的方法、可以呼叫Object.clone方法返回該物件的淺拷貝、支援序列化和反序列化

③、
ArrayList & Vector 提供了隨機訪問功能;
LinkedList 支援雙向佇列

④、
ArrayList & Vector陣列結構,所以改查很快,增刪較慢(又因為 Vector執行緒同步的,所以增刪改查都比 ArrayList 慢)。
LinkedList連結串列結構,所以改查較慢,增刪較快

⑤、
ArrayList & Vector 底層都維護了一個 Object[] 物件陣列用於儲存物件,預設陣列的長度是 10
但是 ArrayList 的物件陣列,通過 transient 修飾,不可序列化

⑥、
Vector 維護了一個 capacityIncrement 欄位,可以通過構造器去設定每次擴容的大小,而 ArrayList 沒有。

⑦、
ArrayList 擴容時,容量自動增長為原來的容量的 1.5 倍
Vector 擴容時,容量自動增長為原來的容量的 2 倍

⑧、
無論哪種,都推薦使用 for-each() 遍歷的方式。

注意:Vector 屬於遺留容器,已經不推薦使用。

Q:但 ArrayList 和 LinkedListed 都是非執行緒安全的,所以如果遇到多個執行緒操作同一個容器的場景,該怎麼處理?
A:可以通過工具類 Collections 中的 synchronizedList() 方法將其轉換成執行緒安全的容器後再使用(這是對裝潢模式的應用,將已有物件傳入另一個類的構造器中建立新的物件來增強實現)。

相關推薦

ArrayListVectorLinkedList區別詳解

一、ArrayList ArrayList是一個可以處理變長陣列的型別,這裡不侷限於“數”組,ArrayList是一個泛型類,可以存放任意型別的物件。顧名思義,ArrayList是一個數組列表,因此其內部是使用一個數組來存放物件的,因為Object是一切型別的父類,因而ArrayList內部是有一個Obje

原始碼淺析 ArrayListVectorLinkedList區別

從類的定義淺析 public class ArrayList<E> extends AbstractList<E> implements List<E

arraylistvectorlinkedList區別

tor arr 系列 mov enc 移除 操作 保存 插入 1、是否同步,看效率 arraylist 和linkedList是線程不安全的,vector是線程安全的。在不要求線程安全的情況下,使用arrayList和linkedList,可以節省同步帶來的開銷,運行效率高

ArrayListVectorLinkedList區別

zed list 使用 mark 使用場景 元素 實現 arraylist 進行 實現方式 ArrayList,Vector 是基於數組的實現。 LinkedList 是基於鏈表的實現。 ? 同步 ArrayList,LinkedList 不是線程安全的。 Ve

ArrayListVectorLinkedList有什麼區別

ArrayList、Vector、LinkedList類均在java.util包中,均為可伸縮陣列,即可以動態改變長度的陣列 一、ArrayList和Vector的區別 儲存結構 ArrayList和Vector是按照順序將元素儲存(從下表為0開始),刪除元素時,刪除操作完成後,需要使部

ArrayListVectorLinkedList區別及其優缺點?HashMapHashTable的區別及其優缺點?

ArrayList、Vector、LinkedList的區別及其優缺點 ArrayList 和Vector是採用陣列方式儲存資料的,是根據索引來訪問元素的,都可以根據需要自動擴充套件內部資料長度,以便增加和插入元素,都允許直接序號索引元素,但是插入資料要涉及到陣列元素移動等

ArrayListvectorLinkedList區別及 內部容器的擴充

ArrayList 和Vector是採用陣列方式儲存資料,此陣列元素數大於實際儲存的資料以便增加和插入元素,都允許直接序號索引元素,但是插入資料要設計到陣列元素移動等記憶體操作,所以索引資料快插入資料慢,Vector由於使用了synchronized方法(執行緒安全)所以效

ArrayListLinkedListVector之間的區別

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

ArrayListVectorLinkedList有什麼區別

ArrayList,Vector、LinkedList類均在java.util包中,均為可伸縮陣列,即可以動態的改變長度的陣列; ArrayList和Vector都是基於儲存元素的Object[ ] array 來實現的,他們會在記憶體中開闢一塊連續的空間來儲存

ArrayListVectorLinkedList區別及其優缺點?

 ArrayList,LinkedList,Vestor這三個類都實現了java.util.List介面,但它們有各自不同的特性,主要如下: 一、同步性 ArrayList,LinkedList是不同步的,而Vestor是同步的。所以如果不要求執行緒安全的話,可以使用A

ArrayListVectorLinkeList的區別

簡單 查找 應該 線性表 n) 長度 數組元素 哈希表 util Arraylist和Vector是采用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加插入元素,都允許直接序號索引元素,但是插入數據要涉及到數組元素移動等內存操作,所以插入數據慢,查找有下標,所以查詢

java集合之列表:ArrayListVectorLinkedList

sta pop arraylist 允許 dex nsa pack java jdk 1 package com.jdk7.chapter4; 2 3 import java.util.ArrayList; 4 import java.util.Link

ArrayListVectorHashMapHashTableHashSet的默認初始容量加載因子擴容增量具體區別

以及 內存 高效率 數組元素 調整 增量 [] key存在 集合 要討論這些常用的默認初始容量和擴容的原因是:當底層實現涉及到擴容時,容器或重新分配一段更大的連續內存(如果是離散分配則不需要重新分配,離散分配都是插入新元素時動態分配內存),要將容器原來的數據全部復制到新的內

ArrayListVectorLinkedList

否則 表示 rec 大小 一次 最大值 array length net List接口特點 1、有序的 collection。 2、可以對列表中每個元素的插入位置進行精確地控制。 3、可以根據元素的索引訪問元素,並搜索列表中的元素。 4、列表通常允許重復的元素。 5、允許存

各種集合框架的總結ArrayListLinkedListVectorHashMapHashTableHashSetLinkedHaSetTreeSetConcurrentHashMap

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

ArrayListVectorLinkedList泛型(Generic)

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

ArrayListVectorLinkedList

xpl oid dom alt sta 鏈表 src exc onu 一、ArrayList分析 1.類和構造方法 public class ArrayList<E> extends AbstractList<E> //可以看到其父類是

Java中 ArrayListVectorLinkedList 的使用和詳解(轉)

import java.util.*; /** * (1)ArrayList是最常用的List實現類,內部是通過陣列實現的,它允許對元素進行快速隨機訪問。陣列的缺點是每個元素之間不能含有“空隙”。 * 當陣列大小不滿足時會增加儲存能力,將已有陣

LinkedListArrayListVectorStack的實現原理和差異

相互關係 LinkedList、ArrayList、Vector 都繼承自 AbstractList;都實現了 List 介面,主要包括 size(), isEmpty(), contains(Ob

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

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