深入學(xué)習(xí)Java之Vector
前言
在前面我們學(xué)習(xí)了關(guān)于List接口中的幾個(gè)實(shí)現(xiàn)ArrayList
智厌、LinkedList
以及Queue接口的實(shí)現(xiàn)ProrityQueue
、接下來我們來學(xué)習(xí)另外一個(gè)比較常用的List接口的實(shí)現(xiàn)Vector
,Vector
屬于元老級別的容器了骆莹,從JDK1.0就已經(jīng)存在了,實(shí)現(xiàn)基本上跟ArrayList
是類似的,只不過由于Vector加多了一些同步機(jī)制莺禁,保證Vector是線程安全的(還記得嗎,之前學(xué)過的那幾個(gè)容器都是非線程安全的)
Vector的繼承結(jié)構(gòu)
首先先來看下Vector的繼承結(jié)構(gòu)
從上圖中可以看到窄赋,Vector所繼承或者實(shí)現(xiàn)的類/接口都是之前所接觸過的哟冬,言下之意,除非Vector自身新增了一些方法忆绰,否則浩峡,Vector的操作方式是跟ArrayList的操作是基本相同的,由于我們在前面的內(nèi)容中已經(jīng)學(xué)習(xí)過了上面所涉及到的相關(guān)接口错敢,這里就不再重復(fù)了翰灾,如果還不是很熟悉的話,可以翻閱前面的內(nèi)容進(jìn)行學(xué)習(xí)
Vector源碼剖析
接下來我們來深入學(xué)習(xí)Vector的源碼
Vector的組成
// 內(nèi)部實(shí)現(xiàn)為Object數(shù)組
protected Object[] elementData;
// 實(shí)際元素的數(shù)量
protected int elementCount;
構(gòu)造方法
// 指定容量以及指定擴(kuò)容時(shí)的增長量
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
// 指定初始化容量稚茅,默認(rèn)擴(kuò)容時(shí)的增長量為0
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
// 空構(gòu)造方法纸淮,默認(rèn)初始化容量為10
public Vector() {
this(10);
}
// 使用容器進(jìn)行構(gòu)造
public Vector(Collection<? extends E> c) {
// 直接將容器轉(zhuǎn)為數(shù)組,并且指向該數(shù)組
elementData = c.toArray();
elementCount = elementData.length;
// 如果容器中元素的類型不是Object亚享,則進(jìn)行轉(zhuǎn)換
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
插入元素
// 需要注意的是咽块,這里的操作使用了synchronized修飾
public synchronized boolean add(E e) {
modCount++;
// 確保容量
ensureCapacityHelper(elementCount + 1);
// 默認(rèn)插入在最后面
elementData[elementCount++] = e;
return true;
}
// 默認(rèn)在最后插入元素
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
// 在指定位置插入元素
public synchronized void insertElementAt(E obj, int index) {
modCount++;
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
ensureCapacityHelper(elementCount + 1);
// 將數(shù)組中index后面的內(nèi)容后移
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
elementData[index] = obj;
elementCount++;
}
// 在指定位置插入元素,這里可以看到欺税,底層是使用insertElementAt方法
public void add(int index, E element) {
insertElementAt(element, index);
}
// 將容器的內(nèi)容插入到Vector中侈沪,默認(rèn)是插入在后面
public synchronized boolean addAll(Collection<? extends E> c) {
modCount++;
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityHelper(elementCount + numNew);
// 直接將a的內(nèi)容拷貝到elementData后面
System.arraycopy(a, 0, elementData, elementCount, numNew);
elementCount += numNew;
return numNew != 0;
}
// 在指定位置加入容器中的所有元素
public synchronized boolean addAll(int index, Collection<? extends E> c) {
modCount++;
if (index < 0 || index > elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityHelper(elementCount + numNew);
int numMoved = elementCount - index;
// 如果需要移動(dòng)的元素大于0,也就是
// 插入的位置不是在當(dāng)前Vector的最后面晚凿,則將index之后的
// 元素先后移
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
// 將新的元素拷貝至當(dāng)前數(shù)組
System.arraycopy(a, 0, elementData, index, numNew);
elementCount += numNew;
return numNew != 0;
}
確保容量以及動(dòng)態(tài)增長
// 確保容量
private void ensureCapacityHelper(int minCapacity) {
// 如果所需要的最小容量大于當(dāng)前數(shù)組的長度亭罪,則進(jìn)行擴(kuò)容
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
// 動(dòng)態(tài)增長
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 如果構(gòu)造Vector的時(shí)候,有傳入增長的數(shù)量歼秽,則使用該數(shù)組
// 否則应役,默認(rèn)的增長為原來容量的一倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
// 如果增長之后發(fā)現(xiàn)小于所需要的最小容量
// 則使用所需的最小容量
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 如果新的容量大于允許的最大值,則不使用該值
// 直接進(jìn)行所需要的最小容量確認(rèn)燥筷,注意扛吞,此時(shí)的最小容量是比較大
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 將舊的數(shù)組中的元素拷貝至新的數(shù)組中
elementData = Arrays.copyOf(elementData, newCapacity);
}
// 最大容量確定
private static int hugeCapacity(int minCapacity) {
// 如果此時(shí)的容量小于0,說明出現(xiàn)了溢出荆责,從上面的內(nèi)容可以
// 知道滥比,minCapacity = elementCount + 新加入的數(shù)據(jù)的長度
// 此時(shí)有可能會(huì)導(dǎo)致整數(shù)溢出,所以需要進(jìn)行特殊判斷
if (minCapacity < 0)
throw new OutOfMemoryError();
// 如果所申請的內(nèi)存大于允許的最大值做院,則使用Integer.MAX_VALUE
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
獲取元素
// 獲取第一個(gè)元素
public synchronized E firstElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}
// 獲取最后一個(gè)元素
public synchronized E lastElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}
// 指定位置的元素
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
// 獲取指定位置的元素
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
// 返回元素盲泛,這里直接將Object類型轉(zhuǎn)化為泛型所指定的類型
E elementData(int index) {
return (E) elementData[index];
}
獲取元素的索引
// 查找指定元素的索引
public int indexOf(Object o) {
return indexOf(o, 0);
}
// 從指定位置開始濒持,查找指定元素的索引
public synchronized int indexOf(Object o, int index) {
// 如果元素是null,則返回第一個(gè)null元素的索引
if (o == null) {
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
// 否則寺滚,返回第一個(gè)匹配的元素的索引
} else {
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i]))
return i;
}
// 如果找不到柑营,則返回-1
return -1;
}
// 從后往前查找第一個(gè)匹配元素的索引
public synchronized int lastIndexOf(Object o) {
return lastIndexOf(o, elementCount-1);
}
// 從指定位置查找,從后往前第一個(gè)匹配的元素的索引
public synchronized int lastIndexOf(Object o, int index) {
if (index >= elementCount)
throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
// 同上
if (o == null) {
for (int i = index; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = index; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
修改元素
// 將指定位置的元素的值設(shè)置為新的值
public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}
// 替換指定位置的元素值村视,并且返回舊值
public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
刪除元素
// 刪除指定位置的元素
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
int numMoved = elementCount - index - 1;
// 如果需要移動(dòng)的元素?cái)?shù)量大于0官套,也就是刪除的元素不是最后一個(gè)元素
// 則將后面的元素前移
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 將最后面的元素(此時(shí)所有的元素已經(jīng)前移了一個(gè)位置)指向null
// 輔助垃圾回收機(jī)制進(jìn)行垃圾回收
elementData[--elementCount] = null;
return oldValue;
}
// 刪除第一個(gè)匹配的元素
public boolean remove(Object o) {
return removeElement(o);
}
// 刪除指定元素
public synchronized boolean removeElement(Object obj) {
modCount++;
// 查找第一個(gè)找到的元素
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}
// 刪除指定位置的元素
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null; /* to let gc do its work */
}
// 刪除指定范圍的元素
protected synchronized void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = elementCount - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// Let gc do its work
int newElementCount = elementCount - (toIndex-fromIndex);
while (elementCount != newElementCount)
elementData[--elementCount] = null;
}
// 刪除所有元素
public synchronized void removeAllElements() {
modCount++;
// 所有元素指向null,方便垃圾回收器進(jìn)行垃圾回收
for (int i = 0; i < elementCount; i++)
elementData[i] = null;
elementCount = 0;
}
// 刪除容量中包含的元素
public synchronized boolean removeAll(Collection<?> c) {
return super.removeAll(c);
}
// 刪除不包含在容器中的元素
public synchronized boolean retainAll(Collection<?> c) {
return super.retainAll(c);
}
// 清除容器中的元素
public void clear() {
removeAllElements();
}
其他常用操作
// 查看是否包含容器中的所有元素
public synchronized boolean containsAll(Collection<?> c) {
return super.containsAll(c);
}
// 將Vector轉(zhuǎn)成array
public synchronized Object[] toArray() {
return Arrays.copyOf(elementData, elementCount);
}
// 將Vector轉(zhuǎn)成array
public synchronized <T> T[] toArray(T[] a) {
if (a.length < elementCount)
return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
System.arraycopy(elementData, 0, a, 0, elementCount);
if (a.length > elementCount)
a[elementCount] = null;
return a;
}
// 查看是否包含某個(gè)元素
public boolean contains(Object o) {
return indexOf(o, 0) >= 0;
}
// 返回枚舉對象
public Enumeration<E> elements() {
return new Enumeration<E>() {
int count = 0;
public boolean hasMoreElements() {
return count < elementCount;
}
public E nextElement() {
synchronized (Vector.this) {
if (count < elementCount) {
return elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
// 判斷是否為空
public synchronized boolean isEmpty() {
return elementCount == 0;
}
// 查看元素個(gè)數(shù)
public synchronized int size() {
return elementCount;
}
// 查看容量
public synchronized int capacity() {
return elementData.length;
}
// 手動(dòng)調(diào)整數(shù)組的大小蚁孔,如果指定的容量比當(dāng)前容量小
// 會(huì)刪除后面的元素
public synchronized void setSize(int newSize) {
modCount++;
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
elementCount = newSize;
}
// 將容量縮減為元素個(gè)數(shù)大小
public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}
// 將數(shù)組的元素拷貝至指定的數(shù)組中
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
總結(jié)
本小節(jié)主要學(xué)習(xí)了Vector奶赔,從上面的代碼分析中可以看到,Vector的基本操作和實(shí)現(xiàn)都是與ArrayList類似的杠氢,不過ArrayList是非線程安全的站刑,而Vector是線程安全的,言下之意鼻百,當(dāng)在多線程環(huán)境下使用List容器時(shí)绞旅,Vector是比較好的選擇,不過温艇,由于進(jìn)行同步等的操作因悲,Vector的效率理論上會(huì)比其他幾個(gè)List的操作低一些,而在非多線程的環(huán)境下勺爱,則可以根據(jù)需要選擇ArrayList或者LinkedList囤捻,以便達(dá)到更高的效率