Java容器類原始碼-Vector的最全的原始碼分析(二)
三、原始碼解讀
1. 繼承、實現
extends:AbstractList<E> implements:List<E>, RandomAccess, Cloneable, java.io.Serializable
2. 全域性變數
(1) 存放資料的陣列
protected Object[] elementData;
(2) 存放數量
protected int elementCount;
(3) 容量增量
protected int capacityIncrement;
3. 構造方法
(1) 不帶引數的構造方法
public Vector() { this(10); }
(2) 帶初始化容量大小的構造方法
/** * @param initialCapacity 初始化容量大小 */ public Vector(int initialCapacity) { this(initialCapacity, 0); }
(3) 帶初始化容量和容量增量的構造方法
/** * @param initialCapacity 初始化容量大小 * @param capacityIncrement 容量增量 */ public Vector(int initialCapacity, int capacityIncrement) { super(); if (initialCapacity < 0) throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); this.elementData = new Object[initialCapacity]; this.capacityIncrement = capacityIncrement; } (4) 帶Colleciton引數的構造方法 /** * @param c 將c轉為Vector */ public Vector(Collection<? extends E> c) { elementData = c.toArray(); elementCount = elementData.length; // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, elementCount, Object[].class); }
4. 方法
(1) public synchronized void copyInto(Object[] anArray)
原始碼解釋:
通過JNI呼叫c++庫的arraycopy方法,實現將anArray陣列複製到當前的Vector。
public synchronized void copyInto(Object[] anArray) { System.arraycopy(elementData, 0, anArray, 0, elementCount); }
(2) public synchronized void trimToSize()
原始碼解釋:
用以優化Vector的記憶體,我們都知道,Vector的每次容量增量是當前大小的2倍,但是當我們沒法用完申請的這麼多記憶體時,我們可以通過呼叫這個方法用以將不需要的記憶體釋放掉。
public synchronized void trimToSize() { modCount++; // 修改次數增加 int oldCapacity = elementData.length; // 獲取到當前的申請的記憶體大小 if (elementCount < oldCapacity) { // 如果當前存放的數量比申請的記憶體要少 elementData = Arrays.copyOf(elementData, elementCount); // 重新為這個陣列申請elementCount大小記憶體,並存放這些資料 } }
(3) public synchronized void ensureCapacity(int minCapacity)
原始碼解釋:
當要擴容時,會呼叫此方法,保證當前容量能存放得下所需要存放的元素數量。如果不夠時,會呼叫grow()方法進行擴容。
public synchronized void ensureCapacity(int minCapacity) { if (minCapacity > 0) { modCount++; ensureCapacityHelper(minCapacity); } } private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); // 如果當前容量比陣列的長度要小時,呼叫grow擴容 } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; /** * Vector的擴容方法, 每次擴容至2倍 * @param minCapacity */ private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; // 獲取到陣列的長度 int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); //如果沒有初始化capacityIncrement,則增加至兩倍 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) // 如果擴容後的容量超過了最大容量 newCapacity = hugeCapacity(minCapacity); // 呼叫hugeCapacity方法 elementData = Arrays.copyOf(elementData, newCapacity); // 將陣列複製到擴容後的新記憶體中去 } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
(4) public synchronized void setSize(int newSize)
原始碼解釋:
修改容量,當newSize比陣列的長度要大時,將其複製到新的記憶體區域,如果要小的話,則從newSize位置到陣列的最後一個位置的所有元素置為空。
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; }
(5) public synchronized int capacity()
原始碼解釋:
返回陣列長度,即申請記憶體的長度。
public synchronized int capacity() { return elementData.length; }
(6) public synchronized int size()
原始碼解釋:
返回陣列已經使用的長度,即存放的資料個數。
public synchronized int size() { return elementCount; }
(7) public synchronized boolean isEmpty()
原始碼解釋:
判空,如果數量為0,即為empty。
public synchronized boolean isEmpty() { return elementCount == 0; }
(8) public Enumeration<E> elements()
原始碼解釋:
返回一個Enumeration物件的序列。Enumeration只有兩個方法,hasMoreElements()和nextElement(),它只能從首個元素遍歷到最後一個元素,並不能根據位置拿到具體的元素。
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"); } }; }
(9) public boolean contains(Object o)
原始碼解釋:
是否包含物件o。呼叫indexOf判斷是否存在。
public boolean contains(Object o) { return indexOf(o, 0) >= 0; } public int indexOf(Object o) { return indexOf(o, 0); }
(10) public synchronized int indexOf(Object o, int index)
原始碼解釋:
判斷o是否為空,如果為空,則遍歷是否存在值為空的元素;不為空,判斷是否存在和o相等的元素。
public synchronized int indexOf(Object o, int index) { 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; } return -1; }
(11) public synchronized int lastIndexOf
原始碼解釋:
獲取該元素所處的最後一個位置,不存在則返回-1
public synchronized int lastIndexOf(Object o) { return lastIndexOf(o, elementCount-1); } 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; }
(12) public synchronized E elementAt(int index)
原始碼解釋:
返回這個位置的元素。其實就是判斷陣列的index位置是否有元素
public synchronized E elementAt(int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } return elementData(index); } E elementData(int index) { return (E) elementData[index]; }
(13) public synchronized E firstElement()
原始碼解釋:
返回陣列第0個位置的元素。
public synchronized E firstElement() { if (elementCount == 0) { throw new NoSuchElementException(); } return elementData(0); }
(14) public synchronized E lastElement()
原始碼解釋:
返回陣列最後一個位置的元素。
public synchronized E lastElement() { if (elementCount == 0) { throw new NoSuchElementException(); } return elementData(elementCount - 1); }
(15) public synchronized void setElementAt(E obj, int index)
原始碼解釋:
修改第index位置的值為obj。其實就是陣列賦值。
public synchronized void setElementAt(E obj, int index) { if (index >= elementCount) { throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount); } elementData[index] = obj; }
每天都在分享文章,也每天都有人想要我出來給大家分享下怎麼去學習Java。大家都知道,我們是學Java全棧的,大家就肯定以為我有全套的Java系統教程。沒錯,我是有Java全套系統教程,進扣裙【47】974【9726】所示,進群的時候記得表明自己想要學習什麼,不要用小號,這樣小編才好給你們發定向資源,今天小編就免費送!~
“我們相信人人都可以成為一個程式設計師,現在開始,找個師兄,帶你入門,學習的路上不再迷茫。這裡是ja+va修真院,初學者轉行到網際網路行業的聚集地。"