第一次例會記錄
Vector可以實現可增長的物件陣列。與陣列一樣,它包含可以使用整數索引進行訪問的元件。不過,Vector的大小是可以增加或者減小的,以便適應建立Vector後進行新增或者刪除操作。
Vector實現List介面,繼承AbstractList類,所以我們可以將其看做佇列,支援相關的新增、刪除、修改、遍歷等功能。
Vector實現RandmoAccess介面,即提供了隨機訪問功能,提供提供快速訪問功能。在Vector我們可以直接訪問元素。
Vector 實現了Cloneable介面,支援clone()方法,可以被克隆。
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Vector提供了四個建構函式:
/** * 構造一個空向量,使其內部資料陣列的大小為 10,其標準容量增量為零。 */ public Vector() { this(10); }
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 構造一個包含指定 collection 中的元素的向量,這些元素按其 collection 的迭代器返回元素的順序排列。 | |
</span><span style="color: #008000">*/</span> |
|
<span style="color: #0000ff">public</span> Vector(Collection<? <span style="color: #0000ff">extends</span> E><span style="color: #000000"> c) { | |
elementData </span>=<span style="color: #000000"> c.toArray(); | |
elementCount </span>=<span style="color: #000000"> elementData.length; |
|
</span><span style="color: #008000">//</span><span style="color: #008000"> c.toArray might (incorrectly) not return Object[] (see 6260652)</span> | |
<span style="color: #0000ff">if</span> (elementData.getClass() != Object[].<span style="color: #0000ff">class</span><span style="color: #000000">) | |
elementData </span>=<span style="color: #000000"> Arrays.copyOf(elementData, elementCount, | |
Object[].</span><span style="color: #0000ff">class</span><span style="color: #000000">); | |
} | |
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 使用指定的初始容量和等於零的容量增量構造一個空向量。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">public</span> Vector(<span style="color: #0000ff">int</span><span style="color: #000000"> initialCapacity) { | |
</span><span style="color: #0000ff">this</span>(initialCapacity, 0<span style="color: #000000">); | |
} | |
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 使用指定的初始容量和容量增量構造一個空的向量。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">public</span> Vector(<span style="color: #0000ff">int</span> initialCapacity, <span style="color: #0000ff">int</span><span style="color: #000000"> capacityIncrement) { | |
</span><span style="color: #0000ff">super</span><span style="color: #000000">(); | |
</span><span style="color: #0000ff">if</span> (initialCapacity < 0<span style="color: #000000">) | |
</span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> IllegalArgumentException("Illegal Capacity: "+<span style="color: #000000"> | |
initialCapacity); | |
</span><span style="color: #0000ff">this</span>.elementData = <span style="color: #0000ff">new</span><span style="color: #000000"> Object[initialCapacity]; | |
</span><span style="color: #0000ff">this</span>.capacityIncrement =<span style="color: #000000"> capacityIncrement; | |
}</span></pre> |
在成員變數方面,Vector提供了elementData , elementCount, capacityIncrement三個成員變數。其中
elementData :"Object[]型別的陣列",它儲存了Vector中的元素。按照Vector的設計elementData為一個動態陣列,可以隨著元素的增加而動態的增長,其具體的增加方式後面提到(ensureCapacity方法)。如果在初始化Vector時沒有指定容器大小,則使用預設大小為10.
elementCount:Vector
物件中的有效元件數。
capacityIncrement:向量的大小大於其容量時,容量自動增加的量。如果在建立Vector時,指定了capacityIncrement的大小;則,每次當Vector中動態陣列容量增加時>,增加的大小都是capacityIncrement。如果容量的增量小於等於零,則每次需要增大容量時,向量的容量將增大一倍。
同時Vector是執行緒安全的!
二、原始碼解析
對於原始碼的解析,LZ在這裡只就增加(add)刪除(remove)兩個方法進行講解。
2.1增加:add(E e)
add(E e):將指定元素新增到此向量的末尾。
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); //確認容器大小,如果操作容量則擴容操作 elementData[elementCount++] = e; //將e元素新增至末尾 return true; }
這個方法相對而言比較簡單,具體過程就是先確認容器的大小,看是否需要進行擴容操作,然後將E元素新增到此向量的末尾。
private void ensureCapacityHelper(int minCapacity) { //如果 if (minCapacity - elementData.length > 0) grow(minCapacity); }
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 進行擴容操作 | |
* 如果此向量的當前容量小於minCapacity,則通過將其內部陣列替換為一個較大的陣列倆增加其容量。 | |
* 新資料陣列的大小姜維原來的大小 + capacityIncrement, | |
* 除非 capacityIncrement 的值小於等於零,在後一種情況下,新的容量將為原來容量的兩倍,不過,如果此大小仍然小於 minCapacity,則新容量將為 minCapacity。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> grow(<span style="color: #0000ff">int</span><span style="color: #000000"> minCapacity) { | |
</span><span style="color: #0000ff">int</span> oldCapacity = elementData.length; <span style="color: #008000">//</span><span style="color: #008000">當前容器大小</span> | |
<span style="color: #008000">/*</span><span style="color: #008000"> | |
* 新容器大小 | |
* 若容量增量係數(capacityIncrement) > 0,則將容器大小增加到capacityIncrement | |
* 否則將容量增加一倍 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">int</span> newCapacity = oldCapacity + ((capacityIncrement > 0) ?<span style="color: #000000"> | |
capacityIncrement : oldCapacity); | |
</span><span style="color: #0000ff">if</span> (newCapacity - minCapacity < 0<span style="color: #000000">) | |
newCapacity </span>=<span style="color: #000000"> minCapacity; | |
</span><span style="color: #0000ff">if</span> (newCapacity - MAX_ARRAY_SIZE > 0<span style="color: #000000">) | |
newCapacity </span>=<span style="color: #000000"> hugeCapacity(minCapacity); | |
elementData </span>=<span style="color: #000000"> Arrays.copyOf(elementData, newCapacity); | |
} | |
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 判斷是否超出最大範圍 | |
* MAX_ARRAY_SIZE:private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">int</span> hugeCapacity(<span style="color: #0000ff">int</span><span style="color: #000000"> minCapacity) { | |
</span><span style="color: #0000ff">if</span> (minCapacity < 0<span style="color: #000000">) | |
</span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span><span style="color: #000000"> OutOfMemoryError(); | |
</span><span style="color: #0000ff">return</span> (minCapacity > MAX_ARRAY_SIZE) ?<span style="color: #000000"> Integer.MAX_VALUE : MAX_ARRAY_SIZE; | |
}</span></pre> |
對於Vector整個的擴容過程,就是根據capacityIncrement確認擴容大小的,若capacityIncrement <= 0 則擴大一倍,否則擴大至capacityIncrement 。當然這個容量的最大範圍為Integer.MAX_VALUE即,2^32 - 1,所以Vector並不是可以無限擴充的。
2.2、remove(Object o)
/** * 從Vector容器中移除指定元素E */ public boolean remove(Object o) { return removeElement(o); }
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">synchronized</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> removeElement(Object obj) { | |
modCount</span>++<span style="color: #000000">; | |
</span><span style="color: #0000ff">int</span> i = indexOf(obj); <span style="color: #008000">//</span><span style="color: #008000">計算obj在Vector容器中位置</span> | |
<span style="color: #0000ff">if</span> (i >= 0<span style="color: #000000">) { | |
removeElementAt(i); </span><span style="color: #008000">//</span><span style="color: #008000">移除</span> | |
<span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; | |
} | |
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">; | |
} | |
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">synchronized</span> <span style="color: #0000ff">void</span> removeElementAt(<span style="color: #0000ff">int</span><span style="color: #000000"> index) { | |
modCount</span>++; <span style="color: #008000">//</span><span style="color: #008000">修改次數+1</span> | |
<span style="color: #0000ff">if</span> (index >= elementCount) { <span style="color: #008000">//</span><span style="color: #008000">刪除位置大於容器有效大小</span> | |
<span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ArrayIndexOutOfBoundsException(index + " >= " +<span style="color: #000000"> elementCount); | |
} | |
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (index < 0) { <span style="color: #008000">//</span><span style="color: #008000">位置小於 < 0</span> | |
<span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span><span style="color: #000000"> ArrayIndexOutOfBoundsException(index); | |
} | |
</span><span style="color: #0000ff">int</span> j = elementCount - index - 1<span style="color: #000000">; | |
</span><span style="color: #0000ff">if</span> (j > 0<span style="color: #000000">) { | |
</span><span style="color: #008000">//</span><span style="color: #008000">從指定源陣列中複製一個數組,複製從指定的位置開始,到目標陣列的指定位置結束。 | |
</span><span style="color: #008000">//</span><span style="color: #008000">也就是陣列元素從j位置往前移</span> | |
System.arraycopy(elementData, index + 1<span style="color: #000000">, elementData, index, j); | |
} | |
elementCount</span>--; <span style="color: #008000">//</span><span style="color: #008000">容器中有效元件個數 - 1</span> | |
elementData[elementCount] = <span style="color: #0000ff">null</span>; <span style="color: #008000">//</span><span style="color: #008000">將向量的末尾位置設定為null</span> | |
}</pre> |
因為Vector底層是使用陣列實現的,所以它的操作都是對陣列進行操作,只不過其是可以隨著元素的增加而動態的改變容量大小,其實現方法是是使用Arrays.copyOf方法將舊資料拷貝到一個新的大容量陣列中。Vector的整個內部實現都比較簡單,這裡就不在重述了。
三、Vector遍歷
Vector支援4種遍歷方式。
3.1、隨機訪問
因為Vector實現了RandmoAccess介面,可以通過下標來進行隨機訪問。
for(int i = 0 ; i < vec.size() ; i++){ value = vec.get(i); }
3.2、迭代器
Iterator it = vec.iterator(); while(it.hasNext()){ value = it.next(); //do something }
3.2、for迴圈
for(Integer value:vec){ //do something }
3.4、Enumeration迴圈
Vector vec = new Vector<>(); Enumeration enu = vec.elements(); while (enu.hasMoreElements()) { value = (Integer)enu.nextElement(); }
Vector可以實現可增長的物件陣列。與陣列一樣,它包含可以使用整數索引進行訪問的元件。不過,Vector的大小是可以增加或者減小的,以便適應建立Vector後進行新增或者刪除操作。
Vector實現List介面,繼承AbstractList類,所以我們可以將其看做佇列,支援相關的新增、刪除、修改、遍歷等功能。
Vector實現RandmoAccess介面,即提供了隨機訪問功能,提供提供快速訪問功能。在Vector我們可以直接訪問元素。
Vector 實現了Cloneable介面,支援clone()方法,可以被克隆。
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Vector提供了四個建構函式:
/** * 構造一個空向量,使其內部資料陣列的大小為 10,其標準容量增量為零。 */ public Vector() { this(10); }
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 構造一個包含指定 collection 中的元素的向量,這些元素按其 collection 的迭代器返回元素的順序排列。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">public</span> Vector(Collection<? <span style="color: #0000ff">extends</span> E><span style="color: #000000"> c) { | |
elementData </span>=<span style="color: #000000"> c.toArray(); | |
elementCount </span>=<span style="color: #000000"> elementData.length; | |
</span><span style="color: #008000">//</span><span style="color: #008000"> c.toArray might (incorrectly) not return Object[] (see 6260652)</span> | |
<span style="color: #0000ff">if</span> (elementData.getClass() != Object[].<span style="color: #0000ff">class</span><span style="color: #000000">) | |
elementData </span>=<span style="color: #000000"> Arrays.copyOf(elementData, elementCount, | |
Object[].</span><span style="color: #0000ff">class</span><span style="color: #000000">); | |
} | |
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 使用指定的初始容量和等於零的容量增量構造一個空向量。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">public</span> Vector(<span style="color: #0000ff">int</span><span style="color: #000000"> initialCapacity) { | |
</span><span style="color: #0000ff">this</span>(initialCapacity, 0<span style="color: #000000">); | |
} | |
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 使用指定的初始容量和容量增量構造一個空的向量。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">public</span> Vector(<span style="color: #0000ff">int</span> initialCapacity, <span style="color: #0000ff">int</span><span style="color: #000000"> capacityIncrement) { | |
</span><span style="color: #0000ff">super</span><span style="color: #000000">(); | |
</span><span style="color: #0000ff">if</span> (initialCapacity < 0<span style="color: #000000">) | |
</span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> IllegalArgumentException("Illegal Capacity: "+<span style="color: #000000"> | |
initialCapacity); | |
</span><span style="color: #0000ff">this</span>.elementData = <span style="color: #0000ff">new</span><span style="color: #000000"> Object[initialCapacity]; | |
</span><span style="color: #0000ff">this</span>.capacityIncrement =<span style="color: #000000"> capacityIncrement; | |
}</span></pre> |
在成員變數方面,Vector提供了elementData , elementCount, capacityIncrement三個成員變數。其中
elementData :"Object[]型別的陣列",它儲存了Vector中的元素。按照Vector的設計elementData為一個動態陣列,可以隨著元素的增加而動態的增長,其具體的增加方式後面提到(ensureCapacity方法)。如果在初始化Vector時沒有指定容器大小,則使用預設大小為10.
elementCount:Vector
物件中的有效元件數。
capacityIncrement:向量的大小大於其容量時,容量自動增加的量。如果在建立Vector時,指定了capacityIncrement的大小;則,每次當Vector中動態陣列容量增加時>,增加的大小都是capacityIncrement。如果容量的增量小於等於零,則每次需要增大容量時,向量的容量將增大一倍。
同時Vector是執行緒安全的!
二、原始碼解析
對於原始碼的解析,LZ在這裡只就增加(add)刪除(remove)兩個方法進行講解。
2.1增加:add(E e)
add(E e):將指定元素新增到此向量的末尾。
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); //確認容器大小,如果操作容量則擴容操作 elementData[elementCount++] = e; //將e元素新增至末尾 return true; }
這個方法相對而言比較簡單,具體過程就是先確認容器的大小,看是否需要進行擴容操作,然後將E元素新增到此向量的末尾。
private void ensureCapacityHelper(int minCapacity) { //如果 if (minCapacity - elementData.length > 0) grow(minCapacity); }
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 進行擴容操作 | |
* 如果此向量的當前容量小於minCapacity,則通過將其內部陣列替換為一個較大的陣列倆增加其容量。 | |
* 新資料陣列的大小姜維原來的大小 + capacityIncrement, | |
* 除非 capacityIncrement 的值小於等於零,在後一種情況下,新的容量將為原來容量的兩倍,不過,如果此大小仍然小於 minCapacity,則新容量將為 minCapacity。 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> grow(<span style="color: #0000ff">int</span><span style="color: #000000"> minCapacity) { | |
</span><span style="color: #0000ff">int</span> oldCapacity = elementData.length; <span style="color: #008000">//</span><span style="color: #008000">當前容器大小</span> | |
<span style="color: #008000">/*</span><span style="color: #008000"> | |
* 新容器大小 | |
* 若容量增量係數(capacityIncrement) > 0,則將容器大小增加到capacityIncrement | |
* 否則將容量增加一倍 | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">int</span> newCapacity = oldCapacity + ((capacityIncrement > 0) ?<span style="color: #000000"> | |
capacityIncrement : oldCapacity); | |
</span><span style="color: #0000ff">if</span> (newCapacity - minCapacity < 0<span style="color: #000000">) | |
newCapacity </span>=<span style="color: #000000"> minCapacity; | |
</span><span style="color: #0000ff">if</span> (newCapacity - MAX_ARRAY_SIZE > 0<span style="color: #000000">) | |
newCapacity </span>=<span style="color: #000000"> hugeCapacity(minCapacity); | |
elementData </span>=<span style="color: #000000"> Arrays.copyOf(elementData, newCapacity); | |
} | |
</span><span style="color: #008000">/**</span><span style="color: #008000"> | |
* 判斷是否超出最大範圍 | |
* MAX_ARRAY_SIZE:private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; | |
</span><span style="color: #008000">*/</span> | |
<span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">int</span> hugeCapacity(<span style="color: #0000ff">int</span><span style="color: #000000"> minCapacity) { | |
</span><span style="color: #0000ff">if</span> (minCapacity < 0<span style="color: #000000">) | |
</span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span><span style="color: #000000"> OutOfMemoryError(); | |
</span><span style="color: #0000ff">return</span> (minCapacity > MAX_ARRAY_SIZE) ?<span style="color: #000000"> Integer.MAX_VALUE : MAX_ARRAY_SIZE; | |
}</span></pre> |
對於Vector整個的擴容過程,就是根據capacityIncrement確認擴容大小的,若capacityIncrement <= 0 則擴大一倍,否則擴大至capacityIncrement 。當然這個容量的最大範圍為Integer.MAX_VALUE即,2^32 - 1,所以Vector並不是可以無限擴充的。
2.2、remove(Object o)
/** * 從Vector容器中移除指定元素E */ public boolean remove(Object o) { return removeElement(o); }
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">synchronized</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> removeElement(Object obj) { | |
modCount</span>++<span style="color: #000000">; | |
</span><span style="color: #0000ff">int</span> i = indexOf(obj); <span style="color: #008000">//</span><span style="color: #008000">計算obj在Vector容器中位置</span> | |
<span style="color: #0000ff">if</span> (i >= 0<span style="color: #000000">) { | |
removeElementAt(i); </span><span style="color: #008000">//</span><span style="color: #008000">移除</span> | |
<span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">; | |
} | |
</span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">; | |
} | |
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">synchronized</span> <span style="color: #0000ff">void</span> removeElementAt(<span style="color: #0000ff">int</span><span style="color: #000000"> index) { | |
modCount</span>++; <span style="color: #008000">//</span><span style="color: #008000">修改次數+1</span> | |
<span style="color: #0000ff">if</span> (index >= elementCount) { <span style="color: #008000">//</span><span style="color: #008000">刪除位置大於容器有效大小</span> | |
<span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> ArrayIndexOutOfBoundsException(index + " >= " +<span style="color: #000000"> elementCount); | |
} | |
</span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (index < 0) { <span style="color: #008000">//</span><span style="color: #008000">位置小於 < 0</span> | |
<span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span><span style="color: #000000"> ArrayIndexOutOfBoundsException(index); | |
} | |
</span><span style="color: #0000ff">int</span> j = elementCount - index - 1<span style="color: #000000">; | |
</span><span style="color: #0000ff">if</span> (j > 0<span style="color: #000000">) { | |
</span><span style="color: #008000">//</span><span style="color: #008000">從指定源陣列中複製一個數組,複製從指定的位置開始,到目標陣列的指定位置結束。 | |
</span><span style="color: #008000">//</span><span style="color: #008000">也就是陣列元素從j位置往前移</span> | |
System.arraycopy(elementData, index + 1<span style="color: #000000">, elementData, index, j); | |
} | |
elementCount</span>--; <span style="color: #008000">//</span><span style="color: #008000">容器中有效元件個數 - 1</span> | |
elementData[elementCount] = <span style="color: #0000ff">null</span>; <span style="color: #008000">//</span><span style="color: #008000">將向量的末尾位置設定為null</span> | |
}</pre> |
因為Vector底層是使用陣列實現的,所以它的操作都是對陣列進行操作,只不過其是可以隨著元素的增加而動態的改變容量大小,其實現方法是是使用Arrays.copyOf方法將舊資料拷貝到一個新的大容量陣列中。Vector的整個內部實現都比較簡單,這裡就不在重述了。
三、Vector遍歷
Vector支援4種遍歷方式。
3.1、隨機訪問
因為Vector實現了RandmoAccess介面,可以通過下標來進行隨機訪問。
for(int i = 0 ; i < vec.size() ; i++){ value = vec.get(i); }
3.2、迭代器
Iterator it = vec.iterator(); while(it.hasNext()){ value = it.next(); //do something }
3.2、for迴圈
for(Integer value:vec){ //do something }
3.4、Enumeration迴圈
Vector vec = new Vector<>(); Enumeration enu = vec.elements(); while (enu.hasMoreElements()) { value = (Integer)enu.nextElement(); }