一、Vector和List的概述
在Java中,Vector和List都是用於存儲一組元素的容器,它們都實現了List接口,因此擁有List特徵:元素可重複,有序。但是,它們之間還存在一些差異。
import java.util.*;
public class Vector_vs_List {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Java");
vector.add("Python");
vector.add("C++");
vector.add("C#");
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C++");
list.add("C#");
System.out.println("Vector: " + vector);
System.out.println("List: " + list);
}
}
以上代碼創建了一個Vector和一個List容器,並將一些元素添加到容器中,然後輸出它們。運行結果:
Vector: [Java, Python, C++, C#]
List: [Java, Python, C++, C#]
Vector和List存儲的數據是一樣的,但是它們的內部實現機制有所不同,下面我們分別進行探究。
二、Vector和List的內部實現
1. Vector的內部實現
Vector是線程安全的,很早就出現在Java中,它的內部實現是採用數組來存儲元素。
當Vector容量不足時,會進行擴容操作,即創建一個更大的數組,將原數組的內容複製到新數組中,增加容量。
默認情況下,Vector容量每次擴增為原來的2倍。即當Vector容量不足時,Vector會創建一個新的長度是原長度2倍的底層數組,將原數組元素複製到新數組,然後再將新增元素添加到數組中。如果Vector中的元素數量不斷增加,就需要不斷進行擴容操作,而且每次擴容都要複製數組,降低了性能。
以下是Vector擴容的代碼示例:
private void grow(int minCapacity) {
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);
elementData = Arrays.copyOf(elementData, newCapacity);
}
其中,minCapacity指的是需要容器具備的最小容量,而capacityIncrement是Vector每次擴容的容量增量。
2. List的內部實現
List的實現類有很多,比如ArrayList、LinkedList等,其中ArrayList是最常用的。
ArrayList也是用數組來存儲元素,但它的擴容機制不同於Vector。當ArrayList容量不足時,會創建一個新數組,並將原數組的內容複製到新數組中,同時利用System.arraycopy方法,實現數組的複製,以此來增加容量。
與Vector不同的是,ArrayList的默認擴容因子是1.5倍,而非2倍。
以下是ArrayList擴容的代碼示例:
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
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);
}
其中,”>>”是位運算符中的右移運算符。如:4 >> 1的結果是2。
三、Vector和List的區別
1. 線程安全性
Vector是線程安全的,因此可以在並發環境中使用。但是,由於線程安全的需求越來越多地被提出,Java官方也在後來的版本中提供了其他數據結構,如ConcurrentHashMap等,替代了許多早期的容器功能。
List是非線程安全的,也就是說,當多個線程同時對一個List進行操作時,可能會破壞原來的數據結構。此時可以採用線程安全的List實現,如CopyOnWriteArrayList。
2. 性能
由於Vector在擴容時必須要複製其內部數組,因此在元素數量較大時,其性能會受到影響。
ArrayList的擴容機制雖然相對於Vector更為高效,但由於其底層還是採用數組實現,因此在插入或刪除元素時,需要移動整個數組的元素,性能也是比LinkedList要低的。
LinkedList在進行插入和刪除操作時,只需要調整前後元素的指針,因此實際上會更為高效。不過,它也有自己的缺點,就是它不支持隨機訪問,如果需要訪問某個元素,只能從頭節點開始不斷遍歷。
3. 使用場景
如果在操作較少的情況下,選擇使用ArrayList可能會更高效,它支持快速隨機訪問,不需要像LinkedList那樣進行遍歷。但如果插入和刪除操作較為頻繁,那就選擇LinkedList更為合適。
另外,如果需要在多線程環境中使用,可以選擇使用ConcurrentHashMap等線程安全的容器。
四、總結
Vector和List都是用於存儲元素的容器,它們的底層實現機制略有不同,Vector的擴容機制性能較低,而ArrayList雖然擴容機制較為高效,但其在插入和刪除操作時也有性能問題。另外,在多線程環境下,需要使用線程安全的容器。
import java.util.*;
public class Vector_vs_List {
public static void main(String[] args) {
Vector<String> vector = new Vector<>();
vector.add("Java");
vector.add("Python");
vector.add("C++");
vector.add("C#");
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C++");
list.add("C#");
System.out.println("Vector: " + vector);
System.out.println("List: " + list);
}
}
原創文章,作者:HBMV,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/137147.html