Java矢量隊列Vector使用示例
概論
學完ArrayList和LinkedList之后,我們接著學習Vector。學習方式還是和之前一樣,先對Vector有個整體認識,然后再學習它的源碼;最后再通過實例來學會使用它。
Vector簡介
Vector 是矢量隊列,它是JDK1.0版本添加的類。繼承于AbstractList,實現了List, RandomAccess, Cloneable這些接口。 Vector 繼承了AbstractList,實現了List;所以,它是一個隊列,支持相關的添加、刪除、修改、遍歷等功能。 Vector 實現了RandmoAccess接口,即提供了隨機訪問功能。RandmoAccess是java中用來被List實現,為List提供快速訪問功能的。在Vector中,我們即可以通過元素的序號快速獲取元素對象;這就是快速隨機訪問。 Vector 實現了Cloneable接口,即實現clone()函數。它能被克隆。
和ArrayList不同,Vector中的操作是線程安全的。
Vector的構造函數
Vector共有4個構造函數 // 默認構造函數 Vector() // capacity是Vector的默認容量大小。當由于增加數據導致容量增加時,每次容量會增加一倍。 Vector(int capacity) // capacity是Vector的默認容量大小,capacityIncrement是每次Vector容量增加時的增量值。 Vector(int capacity, int capacityIncrement) // 創(chuàng)建一個包含collection的Vector Vector(Collection<? extends E> collection)
Vector的API
synchronized booleanadd(E object) void add(int location, E object) synchronized booleanaddAll(Collection<? extends E> collection) synchronized booleanaddAll(int location, Collection<? extends E> collection) synchronized void addElement(E object) synchronized intcapacity() void clear() synchronized Object clone() booleancontains(Object object) synchronized booleancontainsAll(Collection<?> collection) synchronized void copyInto(Object[] elements) synchronized EelementAt(int location) Enumeration<E> elements() synchronized void ensureCapacity(int minimumCapacity) synchronized booleanequals(Object object) synchronized EfirstElement() Eget(int location) synchronized inthashCode() synchronized intindexOf(Object object, int location) intindexOf(Object object) synchronized void insertElementAt(E object, int location) synchronized booleanisEmpty() synchronized ElastElement() synchronized intlastIndexOf(Object object, int location) synchronized intlastIndexOf(Object object) synchronized Eremove(int location) booleanremove(Object object) synchronized booleanremoveAll(Collection<?> collection) synchronized void removeAllElements() synchronized booleanremoveElement(Object object) synchronized void removeElementAt(int location) synchronized booleanretainAll(Collection<?> collection) synchronized Eset(int location, E object) synchronized void setElementAt(E object, int location) synchronized void setSize(int length) synchronized intsize() synchronized List<E>subList(int start, int end) synchronized <T> T[]toArray(T[] contents) synchronized Object[] toArray() synchronized String toString() synchronized void trimToSize()
Vector數據結構
Vector的繼承關系
java.lang.Object ? java.util.AbstractCollection<E> ? java.util.AbstractList<E> ? java.util.Vector<E> public class Vector<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}
Vector與Collection關系如下圖:
Vector的數據結構和ArrayList差不多,它包含了3個成員變量:elementData , elementCount, capacityIncrement
。
(01) elementData 是"Object[]類型的數組",它保存了添加到Vector中的元素。elementData是個動態(tài)數組,如果初始化Vector時,沒指定動態(tài)數組的>大小,則使用默認大小10。隨著Vector中元素的增加,Vector的容量也會動態(tài)增長,capacityIncrement是與容量增長相關的增長系數,具體的增長方式,請參考源碼分析中的ensureCapacity()函數。
(02) elementCount 是動態(tài)數組的實際大小。
(03) capacityIncrement 是動態(tài)數組的增長系數。如果在創(chuàng)建Vector時,指定了capacityIncrement的大?。粍t,每次當Vector中動態(tài)數組容量增加時>,增加的大小都是capacityIncrement。
Vector源碼解析
基于JDK1.6.0_45
為了更了解Vector的原理,下面對Vector源碼代碼作出分析。
package java.util; public class Vector<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable { // 保存Vector中數據的數組protected Object[] elementData;// 實際數據的數量protected int elementCount;// 容量增長系數protected int capacityIncrement;// Vector的序列版本號private static final long serialVersionUID = -2767605614048989439L;// Vector構造函數。默認容量是10。public Vector() {this(10);}// 指定Vector容量大小的構造函數public Vector(int initialCapacity) {this(initialCapacity, 0);}// 指定Vector"容量大小"和"增長系數"的構造函數public Vector(int initialCapacity, int capacityIncrement) {super();if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);// 新建一個數組,數組容量是initialCapacitythis.elementData = new Object[initialCapacity];// 設置容量增長系數this.capacityIncrement = capacityIncrement;}// 指定集合的Vector構造函數。public Vector(Collection<? extends E> c) {// 獲取“集合(c)”的數組,并將其賦值給elementDataelementData = 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);}// 將數組Vector的全部元素都拷貝到數組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);}}// 確認“Vector容量”的幫助函數private void ensureCapacityHelper(int minCapacity) {int oldCapacity = elementData.length;// 當Vector的容量不足以容納當前的全部元素,增加容量大小。// 若 容量增量系數>0(即capacityIncrement>0),則將容量增大當capacityIncrement// 否則,將容量增大一倍。if (minCapacity > oldCapacity) {Object[] oldData = elementData;int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2);if (newCapacity < minCapacity) {newCapacity = minCapacity;}elementData = Arrays.copyOf(elementData, newCapacity);}}// 確定Vector的容量。public synchronized void ensureCapacity(int minCapacity) {// 將Vector的改變統(tǒng)計數+1modCount++;ensureCapacityHelper(minCapacity);}// 設置容量值為 newSizepublic synchronized void setSize(int newSize) {modCount++;if (newSize > elementCount) {// 若 "newSize 大于 Vector容量",則調整Vector的大小。ensureCapacityHelper(newSize);} else {// 若 "newSize 小于/等于 Vector容量",則將newSize位置開始的元素都設置為nullfor (int i = newSize ; i < elementCount ; i++) {elementData[i] = null;}}elementCount = newSize;}// 返回“Vector的總的容量”public synchronized int capacity() {return elementData.length;}// 返回“Vector的實際大小”,即Vector中元素個數public synchronized int size() {return elementCount;}// 判斷Vector是否為空public synchronized boolean isEmpty() {return elementCount == 0;}// 返回“Vector中全部元素對應的Enumeration”public Enumeration<E> elements() {// 通過匿名類實現Enumerationreturn new Enumeration<E>() {int count = 0;// 是否存在下一個元素public boolean hasMoreElements() {return count < elementCount;}// 獲取下一個元素public E nextElement() {synchronized (Vector.this) {if (count < elementCount) {return (E)elementData[count++];}}throw new NoSuchElementException("Vector Enumeration");}};}// 返回Vector中是否包含對象(o)public boolean contains(Object o) {return indexOf(o, 0) >= 0;}// 從index位置開始向后查找元素(o)。// 若找到,則返回元素的索引值;否則,返回-1public synchronized int indexOf(Object o, int index) {if (o == null) {// 若查找元素為null,則正向找出null元素,并返回它對應的序號for (int i = index ; i < elementCount ; i++)if (elementData[i]==null)return i;} else {// 若查找元素不為null,則正向找出該元素,并返回它對應的序號for (int i = index ; i < elementCount ; i++)if (o.equals(elementData[i]))return i;}return -1;}// 查找并返回元素(o)在Vector中的索引值public int indexOf(Object o) {return indexOf(o, 0);}// 從后向前查找元素(o)。并返回元素的索引public synchronized int lastIndexOf(Object o) {return lastIndexOf(o, elementCount-1);}// 從后向前查找元素(o)。開始位置是從前向后的第index個數;// 若找到,則返回元素的“索引值”;否則,返回-1。public synchronized int lastIndexOf(Object o, int index) {if (index >= elementCount)throw new IndexOutOfBoundsException(index + " >= "+ elementCount);if (o == null) {// 若查找元素為null,則反向找出null元素,并返回它對應的序號for (int i = index; i >= 0; i--)if (elementData[i]==null)return i;} else {// 若查找元素不為null,則反向找出該元素,并返回它對應的序號for (int i = index; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}// 返回Vector中index位置的元素。// 若index月結,則拋出異常public synchronized E elementAt(int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);}return (E)elementData[index];}// 獲取Vector中的第一個元素。// 若失敗,則拋出異常!public synchronized E firstElement() {if (elementCount == 0) {throw new NoSuchElementException();}return (E)elementData[0];}// 獲取Vector中的最后一個元素。// 若失敗,則拋出異常!public synchronized E lastElement() {if (elementCount == 0) {throw new NoSuchElementException();}return (E)elementData[elementCount - 1];}// 設置index位置的元素值為objpublic synchronized void setElementAt(E obj, int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);}elementData[index] = obj;}// 刪除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) {System.arraycopy(elementData, index + 1, elementData, index, j);}elementCount--;elementData[elementCount] = null; /* to let gc do its work */}// 在index位置處插入元素(obj)public synchronized void insertElementAt(E obj, int index) {modCount++;if (index > elementCount) {throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount);}ensureCapacityHelper(elementCount + 1);System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);elementData[index] = obj;elementCount++;}// 將“元素obj”添加到Vector末尾public synchronized void addElement(E obj) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = obj;}// 在Vector中查找并刪除元素obj。// 成功的話,返回true;否則,返回false。public synchronized boolean removeElement(Object obj) {modCount++;int i = indexOf(obj);if (i >= 0) {removeElementAt(i);return true;}return false;}// 刪除Vector中的全部元素public synchronized void removeAllElements() {modCount++;// 將Vector中的全部元素設為nullfor (int i = 0; i < elementCount; i++)elementData[i] = null;elementCount = 0;}// 克隆函數public synchronized Object clone() {try {Vector<E> v = (Vector<E>) super.clone();// 將當前Vector的全部元素拷貝到v中v.elementData = Arrays.copyOf(elementData, elementCount);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError();}}// 返回Object數組public synchronized Object[] toArray() {return Arrays.copyOf(elementData, elementCount);}// 返回Vector的模板數組。所謂模板數組,即可以將T設為任意的數據類型public synchronized <T> T[] toArray(T[] a) {// 若數組a的大小 < Vector的元素個數;// 則新建一個T[]數組,數組大小是“Vector的元素個數”,并將“Vector”全部拷貝到新數組中if (a.length < elementCount)return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());// 若數組a的大小 >= Vector的元素個數;// 則將Vector的全部元素都拷貝到數組a中。System.arraycopy(elementData, 0, a, 0, elementCount);if (a.length > elementCount)a[elementCount] = null;return a;}// 獲取index位置的元素public synchronized E get(int index) {if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);return (E)elementData[index];}// 設置index位置的值為element。并返回index位置的原始值public synchronized E set(int index, E element) {if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);Object oldValue = elementData[index];elementData[index] = element;return (E)oldValue;}// 將“元素e”添加到Vector最后。public synchronized boolean add(E e) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = e;return true;}// 刪除Vector中的元素opublic boolean remove(Object o) {return removeElement(o);}// 在index位置添加元素elementpublic void add(int index, E element) {insertElementAt(element, index);}// 刪除index位置的元素,并返回index位置的原始值public synchronized E remove(int index) {modCount++;if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);Object oldValue = elementData[index];int numMoved = elementCount - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index, numMoved);elementData[--elementCount] = null; // Let gc do its workreturn (E)oldValue;}// 清空Vectorpublic void clear() {removeAllElements();}// 返回Vector是否包含集合cpublic synchronized boolean containsAll(Collection<?> c) {return super.containsAll(c);}// 將集合c添加到Vector中public synchronized boolean addAll(Collection<? extends E> c) {modCount++;Object[] a = c.toArray();int numNew = a.length;ensureCapacityHelper(elementCount + numNew);// 將集合c的全部元素拷貝到數組elementData中System.arraycopy(a, 0, elementData, elementCount, numNew);elementCount += numNew;return numNew != 0;}// 刪除集合c的全部元素public synchronized boolean removeAll(Collection<?> c) {return super.removeAll(c);}// 刪除“非集合c中的元素”public synchronized boolean retainAll(Collection<?> c){return super.retainAll(c);}// 從index位置開始,將集合c添加到Vector中public synchronized boolean addAll(int index, Collection<? extends E> c) {modCount++;if (index < 0 || index > elementCount)throw new ArrayIndexOutOfBoundsException(index);Object[] a = c.toArray();int numNew = a.length;ensureCapacityHelper(elementCount + numNew);int numMoved = elementCount - index;if (numMoved > 0)System.arraycopy(elementData, index, elementData, index + numNew, numMoved);System.arraycopy(a, 0, elementData, index, numNew);elementCount += numNew;return numNew != 0;}// 返回兩個對象是否相等public synchronized boolean equals(Object o) {return super.equals(o);}// 計算哈希值public synchronized int hashCode() {return super.hashCode();}// 調用父類的toString()public synchronized String toString() {return super.toString();}// 獲取Vector中fromIndex(包括)到toIndex(不包括)的子集public synchronized List<E> subList(int fromIndex, int toIndex) {return Collections.synchronizedList(super.subList(fromIndex, toIndex), this);}// 刪除Vector中fromIndex到toIndex的元素protected synchronized void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = elementCount - toIndex;System.arraycopy(elementData, toIndex, elementData, fromIndex, numMoved);// Let gc do its workint newElementCount = elementCount - (toIndex-fromIndex);while (elementCount != newElementCount)elementData[--elementCount] = null;}// java.io.Serializable的寫入函數private synchronized void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {s.defaultWriteObject();} }
總結: (01) Vector實際上是通過一個數組去保存數據的。當我們構造Vecotr時;若使用默認構造函數,則Vector的默認容量大小是10。 (02) 當Vector容量不足以容納全部元素時,Vector的容量會增加。若容量增加系數 >0,則將容量的值增加“容量增加系數”;否則,將容量大小增加一倍。 (03) Vector的克隆函數,即是將全部元素克隆到一個數組中。
Vector遍歷方式
Vector支持4種遍歷方式。建議使用下面的第二種去遍歷Vector,因為效率問題。
(01) 第一種,通過迭代器遍歷。即通過Iterator去遍歷。
Integer value = null; int size = vec.size(); for (int i=0; i<size; i++) {value = (Integer)vec.get(i); }
(02) 第二種,隨機訪問,通過索引值去遍歷。 由于Vector實現了RandomAccess接口,它支持通過索引值去隨機訪問元素。
Integer value = null; int size = vec.size(); for (int i=0; i<size; i++) {value = (Integer)vec.get(i); }
(03) 第三種,另一種for循環(huán)。如下:
Integer value = null; for (Integer integ:vec) {value = integ; }
(04) 第四種,Enumeration遍歷。如下:
Integer value = null; Enumeration enu = vec.elements(); while (enu.hasMoreElements()) {value = (Integer)enu.nextElement(); }
測試這些遍歷方式效率的代碼如下:
import java.util.*; /* * @desc Vector遍歷方式和效率的測試程序。 * * @author skywang */ public class VectorRandomAccessTest {public static void main(String[] args) {Vector vec= new Vector();for (int i=0; i<100000; i++)vec.add(i);iteratorThroughRandomAccess(vec) ;iteratorThroughIterator(vec) ;iteratorThroughFor2(vec) ;iteratorThroughEnumeration(vec) ;}private static void isRandomAccessSupported(List list) {if (list instanceof RandomAccess) {System.out.println("RandomAccess implemented!");} else {System.out.println("RandomAccess not implemented!");}}public static void iteratorThroughRandomAccess(List list) {long startTime;long endTime;startTime = System.currentTimeMillis();for (int i=0; i<list.size(); i++) {list.get(i);}endTime = System.currentTimeMillis();long interval = endTime - startTime;System.out.println("iteratorThroughRandomAccess:" + interval+" ms");}public static void iteratorThroughIterator(List list) {long startTime;long endTime;startTime = System.currentTimeMillis();for(Iterator iter = list.iterator(); iter.hasNext(); ) {iter.next();}endTime = System.currentTimeMillis();long interval = endTime - startTime;System.out.println("iteratorThroughIterator:" + interval+" ms");}public static void iteratorThroughFor2(List list) {long startTime;long endTime;startTime = System.currentTimeMillis();for(Object obj:list);endTime = System.currentTimeMillis();long interval = endTime - startTime;System.out.println("iteratorThroughFor2:" + interval+" ms");}public static void iteratorThroughEnumeration(Vector vec) {long startTime;long endTime;startTime = System.currentTimeMillis();for(Enumeration enu = vec.elements(); enu.hasMoreElements(); ) {enu.nextElement();}endTime = System.currentTimeMillis();long interval = endTime - startTime;System.out.println("iteratorThroughEnumeration:" + interval+" ms");} }
運行結果:
iteratorThroughRandomAccess:6 ms iteratorThroughIterator:9 ms iteratorThroughFor2:8 ms iteratorThroughEnumeration:7 ms
總結: 遍歷Vector,使用索引的隨機訪問方式最快,使用迭代器最慢。
Vector示例
下面通過示例學習如何使用Vector
import java.util.Vector; import java.util.List; import java.util.Iterator; import java.util.Enumeration; /** * @desc Vector測試函數:遍歷Vector和常用API */ public class VectorTest {public static void main(String[] args) {// 新建VectorVector vec = new Vector();// 添加元素vec.add("1");vec.add("2");vec.add("3");vec.add("4");vec.add("5");// 設置第一個元素為100vec.set(0, "100");// 將“500”插入到第3個位置vec.add(2, "300");System.out.println("vec:"+vec);// (順序查找)獲取100的索引System.out.println("vec.indexOf(100):"+vec.indexOf("100"));// (倒序查找)獲取100的索引System.out.println("vec.lastIndexOf(100):"+vec.lastIndexOf("100"));// 獲取第一個元素System.out.println("vec.firstElement():"+vec.firstElement());// 獲取第3個元素System.out.println("vec.elementAt(2):"+vec.elementAt(2));// 獲取最后一個元素System.out.println("vec.lastElement():"+vec.lastElement());// 獲取Vector的大小System.out.println("size:"+vec.size());// 獲取Vector的總的容量System.out.println("capacity:"+vec.capacity());// 獲取vector的“第2”到“第4”個元素System.out.println("vec 2 to 4:"+vec.subList(1, 4));// 通過Enumeration遍歷VectorEnumeration enu = vec.elements();while(enu.hasMoreElements())System.out.println("nextElement():"+enu.nextElement());Vector retainVec = new Vector();retainVec.add("100");retainVec.add("300");// 獲取“vec”中包含在“retainVec中的元素”的集合System.out.println("vec.retain():"+vec.retainAll(retainVec));System.out.println("vec:"+vec);// 獲取vec對應的String數組String[] arr = (String[]) vec.toArray(new String[0]);for (String str:arr)System.out.println("str:"+str);// 清空Vector。clear()和removeAllElements()一樣!vec.clear(); //vec.removeAllElements();// 判斷Vector是否為空System.out.println("vec.isEmpty():"+vec.isEmpty());} }
運行結果:
vec:[100, 2, 300, 3, 4, 5] vec.indexOf(100):0 vec.lastIndexOf(100):0 vec.firstElement():100 vec.elementAt(2):300 vec.lastElement():5 size:6 capacity:10 vec 2 to 4:[2, 300, 3] nextElement():100 nextElement():2 nextElement():300 nextElement():3 nextElement():4 nextElement():5 vec.retain():true vec:[100, 300] str:100 str:300 vec.isEmpty():true
到此這篇關于Java矢量隊列Vector使用示例的文章就介紹到這了,更多相關Java Vector內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
詳談hibernate,jpa與spring?data?jpa三者之間的關系
這篇文章主要介紹了hibernate,jpa與spring?data?jpa三者之間的關系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Spring data jpa的使用與詳解(復雜動態(tài)查詢及分頁,排序)
這篇文章主要介紹了Spring data jpa的使用與詳解(復雜動態(tài)查詢及分頁,排序),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-11-11Java中WeakHashMap和HashMap的區(qū)別詳解
這篇文章主要介紹了Java中WeakHashMap和HashMap的區(qū)別詳解,WeakHashMap和HashMap一樣,WeakHashMap也是一個散列表,它存儲的內容也是鍵值對(key-value)映射,而且鍵和值都可以為null,需要的朋友可以參考下2023-09-09Java使用路徑通配符加載Resource與profiles配置使用詳解
這篇文章主要介紹了Java使用路徑通配符加載Resource與profiles配置使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-06-06IntelliJ IDEA搜索整個項目進行全局替換(有危險慎用)
今天小編就為大家分享一篇關于IntelliJ IDEA搜索整個項目進行全局替換(有危險慎用),小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10