Java 集合 ArrayList VS LinkedList VS Vector
共同點:
- 都實現了 List 介面
public class ArrayList<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 class Vector<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
- 都可以插入 null
基本區別:
-
實現方式:
- ArrayList 和 Vector 基於陣列實現,可以隨機訪問,實現了 RandomAccess 介面
- LinkedList 基於連結串列實現,不可隨機訪問,實現了 Deque 介面
-
初始容量:
- ArrayList 初始容量為 10
- Vector 初始容量為 10
- LinkedList 基於連結串列實現,初始容量為 0
-
擴容方式:
- ArrayList 陣列容量不夠時,擴容 50%
int newCapacity = oldCapacity + (oldCapacity >> 1);
- Vector 陣列容量不夠時,擴容 100%
- LinkedList 基於連結串列實現,無需考慮擴容
- ArrayList 陣列容量不夠時,擴容 50%
-
是否執行緒安全:
- ArrayList 執行緒不安全
- Vector 執行緒安全
- LinkedList 執行緒不安全
ArrayList 的實現原理
構造
-
public ArrayList()
可以構造一個預設初始容量為 10 的空列表;private static final int DEFAULT_CAPACITY = 10;
-
public ArrayList(int initialCapacity)
構造一個指定初始容量的空列表; -
public ArrayList(Collection<? extends E> c)
構造一個包含指定 collection 的元素的列表,這些元素按照該 collection 的迭代器返回它們的順序排列的。
調整陣列容量
每當向陣列中新增元素時,都要去檢查新增後元素的個數是否會超出當前陣列的長度,如果超出,陣列將會進行擴容,以滿足新增資料的需求。
陣列擴容有兩個方法:
- 開發者可以通過一個 public 的方法
ensureCapacity(int minCapacity)
來增加 ArrayList 的容量:
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
// any size if not default element table
? 0
// larger than default for default empty table. It's already
// supposed to be at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
- 而在儲存元素等操作過程中,如果遇到容量不足,會呼叫 private 方法
private void ensureCapacityInternal(int minCapacity)
實現:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
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++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 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;
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
陣列的擴容操作的代價是很高的,因此在實際使用時,我們應該儘量避免陣列容量的擴張。
- 當我們可預知要儲存的元素的多少時,要在構造 ArrayList 例項時,就指定其容量,以避免陣列擴容的發生。
- 或者根據實際需求,通過呼叫 ensureCapacity 方法來手動增加 ArrayList 例項的容量。
LinkedList 的實現原理
使用連結串列
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;
}
}
雙端連結串列
/**
* Pointer to first node.
* Invariant: (first == null && last == null) ||
* (first.prev == null && first.item != null)
*/
transient Node<E> first;
/**
* Pointer to last node.
* Invariant: (first == null && last == null) ||
* (last.next == null && last.item != null)
*/
transient Node<E> last;
相關文章
- Java List 常用集合 ArrayList、LinkedList、VectorJava
- List集合總結,對比分析ArrayList,Vector,LinkedList
- Java集合系列(二):ArrayList、LinkedList、Vector的使用方法及區別Java
- java中的List介面(ArrayList、Vector、LinkedList)Java
- java集合【12】——— ArrayList,LinkedList,Vector的相同點與區別是什麼?Java
- 【java】【集合】List的三個子類—ArrayList、Vector、LinkedList的區別和聯絡Java
- 3、List集合——ArrayList、LinkedList
- java複習之 Vector、ArrayList和LinkedList 的區別Java
- LinkedList和ArrayList的區別、Vector和ArrayList的區別
- Java ArrayList 與 LinkedListJava
- List集合(ArrayList-LinkedList);Set集合(HashSet-TreeSet)
- Java集合——LinkedListJava
- java arrayList vector 區別Java
- VS外掛集合
- JAVA集合-ArrayListJava
- Java集合——ArrayListJava
- Java 集合之LinkedListJava
- Java 集合之ArrayListJava
- Java集合之ArrayListJava
- 【Java集合】2 ArrayListJava
- Java集合(一) —— ArrayListJava
- ArrayList、LinkedList和Vector的原始碼解析,帶你走近List的世界原始碼
- 【JavaSE】集合類Collection集合Map集合的簡單介紹,List介面,中三個常用子類ArrayList、Vector、LinkedList之間的比較。Set介面。Java
- 【java】【集合】List、ListIterator、VectorJava
- JAVA集合:LinkedList原始碼解析Java原始碼
- Java集合框架(一)-ArrayListJava框架
- ABAP vs Java, 蛙泳 vs 自由泳Java
- Java中Vector和ArrayList的區別Java
- 【java】【集合】去除ArrayList中的元素、ArrayList巢狀ArrayListJava巢狀
- Java ArrayList 與 LinkedList 的靈活選擇Java
- Rust的Vector vs. Golang的Slice比較RustGolang
- Java集合之LinkedList原始碼解析Java原始碼
- Java集合 LinkedList的原理及使用Java
- Java集合 ArrayList原理及使用Java
- JAVA集合:ArrayList原始碼分析Java原始碼
- 【Java集合】ArrayList原始碼分析Java原始碼
- Java Collection介面 ArrayList集合(容器)Java
- Difference Between Arraylist And Vector : Core Java Interview Collection QuestionJavaView
- Java-ArrayList & LinkedList的原始碼對比分析Java原始碼