Java List 常用集合 ArrayList、LinkedList、Vector
阿新 • • 發佈:2020-09-23
> Java 中的 List 是非常常用的資料型別。List 是有序的 Collection,Java List 一共有三個實現類,分別是:ArrayList、Vector、LinkedList
![](https://img2020.cnblogs.com/blog/1759254/202009/1759254-20200923131703429-1664455962.png)
> 本文分析基於 JDK8
## ArrayList ArrayList 繼承自 AbstractList,實現了 List 介面。底層基於陣列實現容量大小動態變化,初始容量為 10,允許值為 null,有序,非執行緒安全,擅長隨機訪問 ArrayList 還實現了 RandomAccess、Cloneable、Serializable 介面,所以 ArrayList 是支援快速訪問、複製、序列化的 - RandomAccess 標記介面,用來表明其支援快速隨機訪問。如果是實現了這個介面的 List,那麼使用 for 迴圈的方式獲取資料會優於用迭代器獲取資料 - Serializable 標記該類支援序列化 - Cloneable 允許在堆中克隆出一塊和原物件一樣的物件,並將這個物件的地址賦予新的引用。ArrayList 提供的是一種深克隆機制,即克隆除自身物件以外的所有物件,包括自身所包含的所有物件例項。實現方式是先呼叫 super.clone() 方法克隆出一個新物件,然後再手動將原陣列中的值複製到一個新的陣列,並賦值
## LinkedList LinkedList 繼承自 AbstractSequentialList,實現了 List 和 Deque 介面,基於雙向連結串列實現,每個節點都包含了對前一個和後一個元素的引用,可以被當作堆疊、佇列或雙端佇列進行操作,有序,非執行緒安全 ```java // 指向連結串列的第一個節點 transient Node
## Vector Vector 是一個向量佇列,和 ArrayList 類似,繼承自 AbstractList,實現了 List 介面,就連額外介面也是一樣。不同之處在於: - Vector 使用 synchronized 保證執行緒同步 - Vector 中遺留了大量傳統的方法,這些方法不屬於集合框架 Vector 有四個構造方法 ```java // 建立一個預設大小為 10 的向量 public Vector() // 建立指定大小的向量 public Vector(int initialCapacity) // 建立指定大小的向量,並且指定增量。增量表示向量每次增加的元素數目 public Vector(int initialCapacity, int capacityIncrement) // 建立一個包含集合 c 元素的向量 public Vector(Collection extends E> c) ``` Vector 的資料結構和 ArrayList 差不多,它包含了三個成員變數: ```java // 存放元素的動態陣列 protected Object[] elementData; // 動態陣列的實際大小 protected int elementCount; // 動態陣列的增長係數 protected int capacityIncrement; ``` 隨著 Vector 中元素的增加,Vector 的容量也會動態增長,capacityIncrement 是與容量增長相關的增長係數,具體增長細節在 grow 函式中,和 ArrayList 類似 ```java private void grow(int minCapacity) { int oldCapacity = elementData.length; // 如果 capacityIncrement > 0,新的容量大小 = 舊的容量大小 + 增長係數 // 否則容量擴大為原來的兩倍 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); } ```
## Stack Stack 是 Vector 的子類,實現了一個標準的後進先出的棧。Stack 也是通過陣列實現的,當然了,我們也可以將 LinkedList 當作棧來使用 Stack 只定義了預設建構函式,用來建立一個空棧 ```java public Stack() ``` Stack 除了具有 Vector 的所有 API,還有自己實現的方法 ```java // 判斷堆疊是否為空 public boolean empty() // 檢視堆疊頂部的物件,但不從堆疊中移除它 public synchronized E peek() // 移除堆疊頂部的物件,並作為此函式的值返回該物件 public synchronized E pop() // 把物件壓入堆疊頂部 public E push(E item) // 返回物件在堆疊中的位置,以 1 為基數 public synchronized int search(Object o) ``` Stack 的擴容機制基於 Vector,不過由於沒有指定增長係數,所有預設為 0,每次擴容陣列長度增大為原來的兩倍