Vector 介紹
Vector實現了一種可增長的數組對象。它可以像數組一樣,使用index訪問元素。 Vector的大小可以根據需要增加或縮小,以適應Vector創建後添加和刪除項目的需要。Vector 通過維護 capacity 和 capacityIncrement 來優化存儲管理。capacity 的值大於等於Vector的size. Vector 創建後,Vector的存儲量將以塊( capacityIncrement那麼多)的形式增加。
Vector 和 ArrayList的相同點
看代碼:
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//省略
}
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//省略
}
看到沒有,他們繼承了同一個父類ArrayList,實現了同樣的接口 List, RandomAccess, Cloneable, java.io.Serializable。
那奇怪了,豈不是多餘嗎?不是的。往下看:
Vector 和 ArrayList的不同點
第一個不同點,就是他們擴容的方式。ArrayList擴容比較大氣,根據當前的容量來。也就是:newCapacity = oldCapacity + (oldCapacity >> 1);
ArrayList的擴容方式:
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);
}
而Vector比較摳門,每次只增加那麼一點點。capacityIncrement 指定的那麼多。
Vector的擴容方式:
private void grow(int minCapacity) {
// overflow-conscious code
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);
}
那爲什麼Vector那麼扣呢?我覺得是有原因的。Vector和ArrrayList都實現了List接口,Vector用關鍵字 synchronized 修飾了所有的 操作方法,以做到同步。 以remove()方法來說:
ArrayList的實現
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
看看Vector的實現,它在方法內調用的removeElement是使用了synchronized 修飾了的:
public boolean remove(Object o) {
return removeElement(o);
}
public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
他們的size計算方式不一樣
對應ArrayList.他會有個數組 elementData。 還會有一個屬性 size。
在執行add方法的時候,如果成功,會對size進行加一操作。
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
*
* @serial
*/
private int size;
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
但是對於Vector來時,就沒有size這個屬性了。它只有一個elementCount屬性。它在添加一個元素的時候,先判斷是否需要擴容,然後對 elementCount 執行加1操作。
/**
* Sets the size of this vector. If the new size is greater than the
* current size, new {@code null} items are added to the end of
* the vector. If the new size is less than the current size, all
* components at index {@code newSize} and greater are discarded.
*
* @param newSize the new size of this vector
* @throws ArrayIndexOutOfBoundsException if the new size is negative
*/
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;
}
/**
* Adds the specified component to the end of this vector,
* increasing its size by one. The capacity of this vector is
* increased if its size becomes greater than its capacity.
*
* <p>This method is identical in functionality to the
* {@link #add(Object) add(E)}
* method (which is part of the {@link List} interface).
*
* @param obj the component to be added
*/
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
Vector 和 ArrayList相比,還多了一個setSize(int newSize) 操作。就是根據給定的siz大小,如果比現有的elementCount大,就去擴容,如果比現有的elementCount小,就以爲着要搞清洗工作了,就是把超過的元素移出去啦。
/**
* Sets the size of this vector. If the new size is greater than the
* current size, new {@code null} items are added to the end of
* the vector. If the new size is less than the current size, all
* components at index {@code newSize} and greater are discarded.
*
* @param newSize the new size of this vector
* @throws ArrayIndexOutOfBoundsException if the new size is negative
*/
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;
}
Vector還有cpacity()和size()方法,前者表示在不擴容的情況下,可以放多少對象進去。就是它持有對象數組的長度。
size()就是返回一個計數器elementCount.elementCount記錄了到添加了多少個對象進去。
/**
* Returns the current capacity of this vector.
*
* @return the current capacity (the length of its internal
* data array, kept in the field {@code elementData}
* of this vector)
*/
public synchronized int capacity() {
return elementData.length;
}
/**
* Returns the number of components in this vector.
*
* @return the number of components in this vector
*/
public synchronized int size() {
return elementCount;
}