1. 程式人生 > >Java容器類原始碼-Vector的最全的原始碼分析(二)

Java容器類原始碼-Vector的最全的原始碼分析(二)

 

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】所示,進群的時候記得表明自己想要學習什麼,不要用小號,這樣小編才好給你們發定向資源,今天小編就免費送!~

Java容器類原始碼-Vector的最全的原始碼分析(二)

 

“我們相信人人都可以成為一個程式設計師,現在開始,找個師兄,帶你入門,學習的路上不再迷茫。這裡是ja+va修真院,初學者轉行到網際網路行業的聚集地。"