1. 程式人生 > >Java基礎系列(四十三):集合之Vector&Stack

Java基礎系列(四十三):集合之Vector&Stack

Vector

簡介

Vector是一種實現了動態陣列的集合,何為動態陣列呢?即長度可以自動增長的陣列,它是執行緒同步的,也就是說同一時刻只有一個執行緒可以寫Vector,可以避免多執行緒同時寫引起的不一致性,但是比較消耗資源。接下來,我們來看Vector的原始碼。

原始碼

public class Vector<E>
        extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    /**
     *  用於存放集合元素的陣列物件
     */
protected Object[] elementData; /** * 陣列中實際資料的長度 */ protected int elementCount; /** * 陣列的大小大於其該集合容量時,容量自動增加的量。 */ protected int capacityIncrement; /** * 序列化id */ private static final long serialVersionUID = -2767605614048989439L; /** * 建構函式 * @param initialCapacity 初始大小 * @param capacityIncrement 每次擴容的大小 */
public Vector(int initialCapacity, int capacityIncrement) { super(); //如果初始長度小於0,丟擲異常 if (initialCapacity < 0) { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } //new一個Object陣列,長度為initialCapacity this
.elementData = new Object[initialCapacity]; //將每次擴容大小賦給類capacityIncrement this.capacityIncrement = capacityIncrement; } /** * 建構函式 * @param initialCapacity 初始大小 */ public Vector(int initialCapacity) { //預設擴容大小為0 this(initialCapacity, 0); } /** * 無參構造 */ public Vector() { //預設初始大小為10 this(10); } /** * 建構函式 * @param c 引數傳入的是一個集合 */ public Vector(Collection<? extends E> c) { //首先將c轉化為陣列賦給elementData elementData = c.toArray(); elementCount = elementData.length; //如果該陣列的型別不為Object[],則轉換為Object[] if (elementData.getClass() != Object[].class) { elementData = Arrays.copyOf(elementData, elementCount, Object[].class); } } /** * 將集合複製到某個集合中 * @param anArray 複製的目標 */ public synchronized void copyInto(Object[] anArray) { System.arraycopy(elementData, 0, anArray, 0, elementCount); } /** * 這裡的意思是將多餘的容量(即由於動態擴容導致的陣列長度可能會大於資料的長度部分)刪除 */ public synchronized void trimToSize() { modCount++; //陣列的長度 int oldCapacity = elementData.length; //如果資料的長度小於陣列的長度,將動態增長的部分去掉 if (elementCount < oldCapacity) { elementData = Arrays.copyOf(elementData, elementCount); } } /** * 擴容方法 * @param minCapacity 需要的最小容量 */ public synchronized void ensureCapacity(int minCapacity) { //判斷後,將修改值增加1 if (minCapacity > 0) { modCount++; ensureCapacityHelper(minCapacity); } } /** * 擴容橋方法 * @param minCapacity 需要的最小容量 */ private void ensureCapacityHelper(int minCapacity) { //如果需要的最小容量大於當前陣列的長度,呼叫擴容方法 if (minCapacity - elementData.length > 0) { grow(minCapacity); } } /** * 集合最大長度為Integer的最大值-8, * 因為陣列作為一個物件,需要一定的記憶體儲存物件頭資訊,物件頭資訊最大佔用記憶體不可超過8 byte */ private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * 擴容方法實現 * @param minCapacity 需要的最小容量 */ private void grow(int minCapacity) { //獲取當前陣列的長度 int oldCapacity = elementData.length; //如果設定了自動擴容的長度,就按照自動擴容的長度,否則翻倍 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //如果新的長度小於該陣列需要的最小長度,將該最小長度賦給newCapacity if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } //如果新的長度大於陣列最大長度 if (newCapacity - MAX_ARRAY_SIZE > 0) { //呼叫這個檢查是否超過Integer的最大值,這裡體現了設計的嚴謹,實際上這裡很少會去呼叫 newCapacity = hugeCapacity(minCapacity); } //最後按照新的長度將陣列資訊拷貝到一個新的陣列物件中後賦給原陣列物件 elementData = Arrays.copyOf(elementData, newCapacity); } /** * 用於判斷集合的值會不會溢位,一般很少會呼叫到這個方法 * @param minCapacity * @return */ private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) { throw new OutOfMemoryError(); } return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } /** * 給該集合容器設定新的大小 * @param newSize */ public synchronized void setSize(int newSize) { modCount++; //如果設定的長度大於該陣列的長度,進行擴容 if (newSize > elementCount) { ensureCapacityHelper(newSize); } else { //反之將超出newSize的部分賦予null for (int i = newSize ; i < elementCount ; i++) { elementData[i] = null; } } //將新的長度賦給陣列的長度 elementCount = newSize; } /** * 獲取當前陣列的長度 * @return 返回的是當前陣列物件的長度 */ public synchronized int capacity() { return elementData.length; } /** * 返回的是陣列中資料的長度,因為由於動態擴容,資料的長度可能會小於陣列的長度 * @return 返回的是陣列中陣列的長度 */ @Override public synchronized int size() { return elementCount; } /** * 判斷集合中的元素個數是否為空 * @return 返回布林值,為空返回true,不為空返回false */ @Override public synchronized boolean isEmpty() { return elementCount == 0; } /** * 返回此集合的元件的列舉。返回的 Enumeration 物件將生成此向量中的所有項。生成的第一項為索引0處的項,然後是索引1處的項。 * @return 此集合的元件的列舉 */ public Enumeration<E> elements() { //返回的是一個內部類 return new Enumeration<E>() { /** * 列舉的索引 */ int count = 0; /** * 是否有下一個列舉項 */ @Override public boolean hasMoreElements() { return count < elementCount; } /** * 獲取下一個列舉項 * @return 返回的是下一位索引的列舉 */ @Override public E nextElement() { synchronized (Vector.this) { if (count < elementCount) { //將索引+1 return elementData(count++); } } throw new NoSuchElementException("Vector Enumeration"); } }; } /** * 判斷集合中是否包含物件o * @param o 判斷集合中是否包含該物件 * @return 返回布林值,包含返回true,不包含返回false */ @Override public boolean contains(Object o) { //通過indexOf判斷是否存在該元素 return indexOf(o, 0) >= 0; } /** * 判斷集合中某個元素的索引位置 * @param o 用於判斷位置的元素 * @return 返回該元素位於集合的索引值 */ @Override public int indexOf(Object o) { return indexOf(o, 0); } /** * 判斷某個元素相對於某個索引開始的索引值 * @param o 用於判斷的元素 * @param index 相對位置的索引 * @return 返回的是相對於index的索引值 */ public synchronized int indexOf(Object o, int index) { //分為兩種情況進行判斷為null和不為null if (o == null) { for (int i = index ; i < elementCount ; i++) { if (elementData[i]==null) { return i; } } } else { for (int i = index ; i < elementCount ; i++) { if (o.equals(elementData[i])) { return i; } } } //如果不存在,返回-1 return -1; } /** * 返回某個元素最後一次出現在集合中的索引值 * @param o 用於判斷位置的元素 * @return */ @Override public synchronized int lastIndexOf(Object o) { //基於某個索引的最後一次出現的位置索引,預設為最後一位 return lastIndexOf(o, elementCount-1); } /** * 返回某個元素最後一次出現位置的索引 * @param o 用於判斷位置的元素 * @param index 用於判斷位置的相對索引 * @return 返回該判斷元素相對於索引位置最後一次出現的位置的索引 */ public synchronized int lastIndexOf(Object o, int index) { //如果索引值大於陣列長度,丟擲一個異常 if (index >= elementCount) { throw new IndexOutOfBoundsException(index + " >= "+ elementCount); } //使用反向遍歷,原理和indexOf一致 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; } } } //不存在,返回-1 return -1; } /** * 返回該集合中某個索引位置的元素 * @param index 索引值 * @return 位於該集合中索引值的元素 */ public synchronized E elementAt(int index) { //如果索引值大於陣列長度,丟擲一個異常 if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } //返回位於該索引的元素 return elementData(index); } /** * 返回該集合中的第一個元素 * @return 該集合中的第一個元素 */ public synchronized E firstElement() { //如果集合為空,丟擲一個異常 if (elementCount == 0) { throw new NoSuchElementException(); } return elementData(0); } /** * 返回該集合中的最後一個元素 * @return 返回該集合中的最後一個元素 */ public synchronized E lastElement() { //如果集合為空,丟擲一個異常 if (elementCount == 0) { throw new NoSuchElementException(); } return elementData(elementCount - 1); } /** * 將某個物件賦予集合中的某個索引位置 * @param obj 賦予某個物件 * @param index 索引值 */ public synchronized void setElementAt(E obj, int index) { //如果索引值大於陣列長度,丟擲一個異常 if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } //將obj賦給陣列中的第index項 elementData[index] = obj; } /** * 刪除位於某個位置的元素 * @param index 該位置的索引值 */ 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) { //arraycopy的含義是將elementData數組裡從索引為index + 1的元素開始, 複製到陣列elementData裡的索引為index的位置, 複製的元素個數為j個. //相當於用後兩個代替了後三個,將位於index位置的元素刪除 System.arraycopy(elementData, index + 1, elementData, index, j); } elementCount--; //刪除後,將最後一位置為null elementData[elementCount] = null; } /** * 在某個位置新增元素 * @param obj 需要新增的元素 * @param index 需要新增的位置 */ public synchronized void insertElementAt(E obj, int index) { modCount++; if (index > elementCount) { throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount); } //將陣列的長度擴大一 ensureCapacityHelper(elementCount + 1); //和remove的原理類似,將位於index項後的拷貝到index+1位置,相當於在index位置元素複製一個元素 System.arraycopy(elementData, index, elementData, index + 1, elementCount - index); //將obj賦予陣列位於index的位置 elementData[index] = obj; elementCount++; } /** * 在元素的末尾新增一個元素 * @param obj 需要新增的元素 */ public synchronized void addElement(E obj) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = obj; } /** * 刪除某個元素 * @param obj 需要刪除的元素 * @return 刪除成功返回true,刪除失敗返回fasle */ public synchronized boolean removeElement(Object obj) { modCount++; int i = indexOf(obj); if (i >= 0) { removeElementAt(i); return true; } return false; } /** * 刪除所有元素 */ public synchronized void removeAllElements() { modCount++; for (int i = 0; i < elementCount; i++) { elementData[i] = null; } elementCount = 0; } /** * 克隆一個新物件 * @return 返回的是克隆得到的物件 */ @Override public synchronized Object clone() { try { @SuppressWarnings("unchecked") Vector<E> v = (Vector<E>) super.clone(); v.elementData = Arrays.copyOf(elementData, elementCount); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } } /** * 將該集合轉化為陣列 * @return 返回的是轉化後的陣列 */ @Override public synchronized Object[] toArray() { return Arrays.copyOf(elementData, elementCount); } /** * 將該集合轉化為某種型別的陣列 * @param a 需要轉化的型別 * @param <T> 返回的陣列型別 * @return 返回的陣列 */ @Override @SuppressWarnings("unchecked") 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; } /** * 獲取位於某個索引的元素 * @param index 索引值 * @return 該索引值的元素 */ @SuppressWarnings("unchecked") E elementData(int index) { return (E) elementData[index]; } /** * 獲取位於某個位置的元素 * @param index 該位置的索引 * @return 該位置的元素 */ @Override public synchronized E get(int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index); } return elementData(index); } /** * 將某個索引的位置設定為某個元素 * @param index 索引 * @param element 將該物件替代該索引位置的元素 * @return 返回的是被替代的元素 */ @Override public synchronized E set(int index, E element) { if (index >= elementCount) { throw<