鍍金池/ 教程/ Java/ Vector
Java 集合細(xì)節(jié)(四):保持 compareTo 和 equals 同步
Iterator
使用序列化實(shí)現(xiàn)對象的拷貝
fail-fast 機(jī)制
關(guān)鍵字 final
Vector
HashTable
Java 集合細(xì)節(jié)(一):請為集合指定初始容量
強(qiáng)制類型轉(zhuǎn)換
數(shù)組之一:認(rèn)識 JAVA 數(shù)組
Java 集合細(xì)節(jié)(三):subList 的缺陷
hashCode
ArrayList
數(shù)組之二
List 總結(jié)
LinkedList
Java 提高篇(九)—–實(shí)現(xiàn)多重繼承
Java 的四舍五入
關(guān)鍵字 static
理解 Java 的三大特性之多態(tài)
抽象類與接口
集合大家族
異常(二)
Java 集合細(xì)節(jié)(二):asList 的缺陷
Map 總結(jié)
TreeSet
equals() 方法總結(jié)
Java 提高篇(十)—–詳解匿名內(nèi)部類
HashMap
Stack
詳解內(nèi)部類
TreeMap
異常(一)
詳解 Java 定時(shí)任務(wù)
HashSet
字符串
理解 Java 的三大特性之繼承
理解 Java 的三大特性之封裝
代碼塊

Vector

Java提高篇(二一)—–ArrayList 、Java 提高篇(二二)—LinkedList ,詳細(xì)講解了 ArrayList、linkedList 的原理和實(shí)現(xiàn)過程,對于 List 接口這里還介紹一個(gè)它的實(shí)現(xiàn)類 Vector,Vector 類可以實(shí)現(xiàn)可增長的對象數(shù)組。

一、Vector 簡介

Vector 可以實(shí)現(xiàn)可增長的對象數(shù)組。與數(shù)組一樣,它包含可以使用整數(shù)索引進(jìn)行訪問的組件。不過,Vector 的大小是可以增加或者減小的,以便適應(yīng)創(chuàng)建 Vector 后進(jìn)行添加或者刪除操作。

Vector 實(shí)現(xiàn) List 接口,繼承 AbstractList 類,所以我們可以將其看做隊(duì)列,支持相關(guān)的添加、刪除、修改、遍歷等功能。

Vector 實(shí)現(xiàn) RandmoAccess 接口,即提供了隨機(jī)訪問功能,提供提供快速訪問功能。在 Vector 我們可以直接訪問元素。

Vector 實(shí)現(xiàn)了 Cloneable 接口,支持 clone() 方法,可以被克隆。


    public class Vector<E>
        extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

Vector 提供了四個(gè)構(gòu)造函數(shù):


    /**
         * 構(gòu)造一個(gè)空向量,使其內(nèi)部數(shù)據(jù)數(shù)組的大小為 10,其標(biāo)準(zhǔn)容量增量為零。
         */
         public Vector() {
                this(10);
         }

        /**
         * 構(gòu)造一個(gè)包含指定 collection 中的元素的向量,這些元素按其 collection 的迭代器返回元素的順序排列。
         */
        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);
        }

        /**
         * 使用指定的初始容量和等于零的容量增量構(gòu)造一個(gè)空向量。
         */
         public Vector(int initialCapacity) {
            this(initialCapacity, 0);
        }

        /**
         *  使用指定的初始容量和容量增量構(gòu)造一個(gè)空的向量。
         */
        public Vector(int initialCapacity, int capacityIncrement) {
            super();
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal Capacity: "+
                                                  initialCapacity);
            this.elementData = new Object [initialCapacity];
            this.capacityIncrement = capacityIncrement;
        }

在成員變量方面,Vector 提供了 elementData , elementCount, capacityIncrement 三個(gè)成員變量。其中

elementData :”O(jiān)bject[] 類型的數(shù)組”,它保存了 Vector 中的元素。按照 Vector 的設(shè)計(jì) elementData 為一個(gè)動態(tài)數(shù)組,可以隨著元素的增加而動態(tài)的增長,其具體的增加方式后面提到(ensureCapacity 方法)。如果在初始化 Vector 時(shí)沒有指定容器大小,則使用默認(rèn)大小為 10.

elementCount:Vector 對象中的有效組件數(shù)。

capacityIncrement:向量的大小大于其容量時(shí),容量自動增加的量。如果在創(chuàng)建 Vector 時(shí),指定了 capacityIncrement 的大?。粍t,每次當(dāng) Vector 中動態(tài)數(shù)組容量增加時(shí)>,增加的大小都是 capacityIncrement。如果容量的增量小于等于零,則每次需要增大容量時(shí),向量的容量將增大一倍。

同時(shí) Vector 是線程安全的!

二、源碼解析

對于源碼的解析,LZ 在這里只就增加(add)刪除(remove)兩個(gè)方法進(jìn)行講解。

2.1增加:add(E e)

add(E e):將指定元素添加到此向量的末尾。


    public synchronized boolean add(E e) {
            modCount++;     
            ensureCapacityHelper(elementCount + 1);    //確認(rèn)容器大小,如果操作容量則擴(kuò)容操作
            elementData[elementCount++] = e;   //將e元素添加至末尾
            return true;
        }

這個(gè)方法相對而言比較簡單,具體過程就是先確認(rèn)容器的大小,看是否需要進(jìn)行擴(kuò)容操作,然后將E元素添加到此向量的末尾。


    private void ensureCapacityHelper(int minCapacity) {
            //如果
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }

        /**
         * 進(jìn)行擴(kuò)容操作
         * 如果此向量的當(dāng)前容量小于minCapacity,則通過將其內(nèi)部數(shù)組替換為一個(gè)較大的數(shù)組倆增加其容量。
         * 新數(shù)據(jù)數(shù)組的大小姜維原來的大小 + capacityIncrement,
         * 除非 capacityIncrement 的值小于等于零,在后一種情況下,新的容量將為原來容量的兩倍,不過,如果此大小仍然小于 minCapacity,則新容量將為 minCapacity。
         */
        private void grow(int minCapacity) {
            int oldCapacity = elementData.length;     //當(dāng)前容器大小
            /*
             * 新容器大小
             * 若容量增量系數(shù)(capacityIncrement) > 0,則將容器大小增加到capacityIncrement
             * 否則將容量增加一倍
             */
            int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                            capacityIncrement : oldCapacity);

            if (newCapacity - minCapacity < 0)
                newCapacity = minCapacity;

            if (newCapacity - MAX_ARRAY_SIZE > 0)
                newCapacity = hugeCapacity(minCapacity);

            elementData = Arrays.copyOf(elementData, newCapacity);
        }

        /**
         * 判斷是否超出最大范圍
         * MAX_ARRAY_SIZE:private static final int  MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
         */
        private static int hugeCapacity(int minCapacity) {
            if (minCapacity < 0)
                throw new OutOfMemoryError();
            return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
        }

對于 Vector 整個(gè)的擴(kuò)容過程,就是根據(jù) capacityIncrement 確認(rèn)擴(kuò)容大小的,若 capacityIncrement <= 0 則擴(kuò)大一倍,否則擴(kuò)大至 capacityIncrement 。當(dāng)然這個(gè)容量的最大范圍為 Integer.MAX_VALUE即,2^32 – 1,所以 Vector 并不是可以無限擴(kuò)充的。

2.2、remove(Object o)


    /**
         * 從Vector容器中移除指定元素E
         */
        public boolean remove(Object o) {
            return removeElement(o);
        }

        public synchronized boolean removeElement(Object obj) {
            modCount++;
            int i = indexOf(obj);   //計(jì)算obj在Vector容器中位置
            if (i >= 0) {
                removeElementAt(i);   //移除
                return true;
            }
            return false;
        }

        public synchronized void removeElementAt(int index) {
            modCount++;     //修改次數(shù)+1
            if (index >= elementCount) {   //刪除位置大于容器有效大小
                throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
            }
            else if (index < 0) {    //位置小于 < 0
                throw new ArrayIndexOutOfBoundsException(index);
            }
            int j = elementCount - index - 1;
            if (j > 0) {   
                //從指定源數(shù)組中復(fù)制一個(gè)數(shù)組,復(fù)制從指定的位置開始,到目標(biāo)數(shù)組的指定位置結(jié)束。
                //也就是數(shù)組元素從j位置往前移
                System.arraycopy(elementData, index + 1, elementData, index, j);
            }
            elementCount--;   //容器中有效組件個(gè)數(shù) - 1
            elementData[elementCount] = null;    //將向量的末尾位置設(shè)置為null
        }

因?yàn)?Vector 底層是使用數(shù)組實(shí)現(xiàn)的,所以它的操作都是對數(shù)組進(jìn)行操作,只不過其是可以隨著元素的增加而動態(tài)的改變?nèi)萘看笮?,其?shí)現(xiàn)方法是是使用 Arrays.copyOf 方法將舊數(shù)據(jù)拷貝到一個(gè)新的大容量數(shù)組中。 Vector 的整個(gè)內(nèi)部實(shí)現(xiàn)都比較簡單,這里就不在重述了。

三、Vector 遍歷

Vector 支持 4 種遍歷方式。

3.1、隨機(jī)訪問

因?yàn)?Vector 實(shí)現(xiàn)了 RandmoAccess 接口,可以通過下標(biāo)來進(jìn)行隨機(jī)訪問。


    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.3、for 循環(huán)


    for(Integer value:vec){
            //do something
        }

3.4、Enumeration 循環(huán)


    Vector vec = new Vector<>();
        Enumeration enu = vec.elements();
        while (enu.hasMoreElements()) {
            value = (Integer)enu.nextElement();
        }
上一篇:關(guān)鍵字 static下一篇:hashCode