原始碼淺析 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() 實現更加簡單,且速度沒慢太多,推薦使用。
LinkedList,for-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() 方法將其轉換成執行緒安全的容器後再使用(這是對裝潢模式的應用,將已有物件傳入另一個類的構造器中建立新的物件來增強實現)。
相關推薦
ArrayList,Vector和LinkedList區別詳解
一、ArrayList ArrayList是一個可以處理變長陣列的型別,這裡不侷限於“數”組,ArrayList是一個泛型類,可以存放任意型別的物件。顧名思義,ArrayList是一個數組列表,因此其內部是使用一個數組來存放物件的,因為Object是一切型別的父類,因而ArrayList內部是有一個Obje
原始碼淺析 ArrayList、Vector、LinkedList 的區別
從類的定義淺析 public class ArrayList<E> extends AbstractList<E> implements List<E
arraylist、vector、linkedList的區別
tor arr 系列 mov enc 移除 操作 保存 插入 1、是否同步,看效率 arraylist 和linkedList是線程不安全的,vector是線程安全的。在不要求線程安全的情況下,使用arrayList和linkedList,可以節省同步帶來的開銷,運行效率高
ArrayList、Vector和LinkedList的區別
zed list 使用 mark 使用場景 元素 實現 arraylist 進行 實現方式 ArrayList,Vector 是基於數組的實現。 LinkedList 是基於鏈表的實現。 ? 同步 ArrayList,LinkedList 不是線程安全的。 Ve
ArrayList、Vector和LinkedList有什麼區別
ArrayList、Vector、LinkedList類均在java.util包中,均為可伸縮陣列,即可以動態改變長度的陣列 一、ArrayList和Vector的區別 儲存結構 ArrayList和Vector是按照順序將元素儲存(從下表為0開始),刪除元素時,刪除操作完成後,需要使部
ArrayList、Vector、LinkedList的區別及其優缺點?HashMap、HashTable的區別及其優缺點?
ArrayList、Vector、LinkedList的區別及其優缺點 ArrayList 和Vector是採用陣列方式儲存資料的,是根據索引來訪問元素的,都可以根據需要自動擴充套件內部資料長度,以便增加和插入元素,都允許直接序號索引元素,但是插入資料要涉及到陣列元素移動等
ArrayList、vector、LinkedList的區別及 內部容器的擴充
ArrayList 和Vector是採用陣列方式儲存資料,此陣列元素數大於實際儲存的資料以便增加和插入元素,都允許直接序號索引元素,但是插入資料要設計到陣列元素移動等記憶體操作,所以索引資料快插入資料慢,Vector由於使用了synchronized方法(執行緒安全)所以效
ArrayList、LinkedList、Vector之間的區別
①ArrayList:內部採用陣列儲存元素,支援高效隨機訪問,支援動態調整大小;更適合遍歷查詢,增刪改查的效率相對低; ②LinkedList:內部採用連結串列來儲存元素,支援快速插入/刪除元素,但不支援高效地隨機訪問;更適合增刪改,遍歷效率相對低[無同步];
ArrayList、Vector、LinkedList有什麼區別?
ArrayList,Vector、LinkedList類均在java.util包中,均為可伸縮陣列,即可以動態的改變長度的陣列; ArrayList和Vector都是基於儲存元素的Object[ ] array 來實現的,他們會在記憶體中開闢一塊連續的空間來儲存
ArrayList、Vector、LinkedList的區別及其優缺點?
ArrayList,LinkedList,Vestor這三個類都實現了java.util.List介面,但它們有各自不同的特性,主要如下: 一、同步性 ArrayList,LinkedList是不同步的,而Vestor是同步的。所以如果不要求執行緒安全的話,可以使用A
ArrayList和Vector、LinkeList的區別
簡單 查找 應該 線性表 n) 長度 數組元素 哈希表 util Arraylist和Vector是采用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加插入元素,都允許直接序號索引元素,但是插入數據要涉及到數組元素移動等內存操作,所以插入數據慢,查找有下標,所以查詢
java集合之列表:ArrayList、Vector、LinkedList
sta pop arraylist 允許 dex nsa pack java jdk 1 package com.jdk7.chapter4; 2 3 import java.util.ArrayList; 4 import java.util.Link
ArrayList、Vector、HashMap、HashTable、HashSet的默認初始容量、加載因子、擴容增量、具體區別
以及 內存 高效率 數組元素 調整 增量 [] key存在 集合 要討論這些常用的默認初始容量和擴容的原因是:當底層實現涉及到擴容時,容器或重新分配一段更大的連續內存(如果是離散分配則不需要重新分配,離散分配都是插入新元素時動態分配內存),要將容器原來的數據全部復制到新的內
ArrayList、Vector和LinkedList
否則 表示 rec 大小 一次 最大值 array length net List接口特點 1、有序的 collection。 2、可以對列表中每個元素的插入位置進行精確地控制。 3、可以根據元素的索引訪問元素,並搜索列表中的元素。 4、列表通常允許重復的元素。 5、允許存
各種集合框架的總結ArrayList、LinkedList、Vector、HashMap、HashTable、HashSet、LinkedHaSet、TreeSet、ConcurrentHashMap
這幾道Java集合框架面試題在面試中幾乎必問 1.Arraylist 與 LinkedList 異同 1. 執行緒安全: ArrayList 和 LinkedList 都是執行緒不安全的; 2. 資料結構: Arraylist 底層使用的是Object陣列;Linked
ArrayList、Vector、LinkedList、泛型(Generic)
1.ArrayList、Vector、LinkedList ArrayList儲存字串並遍歷 void forEach(Consumer<? super E> action) 執行特定動作的每一個元素的 Iterable直到所有元素都被處理或操作丟擲
ArrayList、Vector、LinkedList
xpl oid dom alt sta 鏈表 src exc onu 一、ArrayList分析 1.類和構造方法 public class ArrayList<E> extends AbstractList<E> //可以看到其父類是
Java中 ArrayList、Vector和LinkedList 的使用和詳解(轉)
import java.util.*; /** * (1)ArrayList是最常用的List實現類,內部是通過陣列實現的,它允許對元素進行快速隨機訪問。陣列的缺點是每個元素之間不能含有“空隙”。 * 當陣列大小不滿足時會增加儲存能力,將已有陣
LinkedList、ArrayList、Vector、Stack的實現原理和差異
相互關係 LinkedList、ArrayList、Vector 都繼承自 AbstractList;都實現了 List 介面,主要包括 size(), isEmpty(), contains(Ob
java的list幾種實現方式的效率(ArrayList、LinkedList、Vector、Stack),以及 java時間戳的三種獲取方式比較
一、list簡介 List列表類,順序儲存任何物件(順序不變),可重複。 List是繼承於Collection的介面,不能例項化。例項化可以用: ArrayList(實現動態陣列),查詢快(隨