Collection-Vector

jdk版本:1.8.0_77
參考文檔:jdk 1.8 docs

Vector類圖

Vector繼承關(guān)系

Vector特點(diǎn)

  1. Vector對(duì)象內(nèi)部維護(hù)一個(gè)數(shù)組對(duì)象薪丁,可以通過整數(shù)索引訪問數(shù)組元素。
protected Object[] elementData;//存儲(chǔ)對(duì)象的數(shù)組緩沖區(qū)
protected int elementCount;//Vector存儲(chǔ)的元素個(gè)數(shù)
protected int capacityIncrement;//當(dāng)Vector容量不夠擴(kuò)容大小
  1. Vector通過設(shè)置capacity、capacityIncrement參數(shù)來優(yōu)化存儲(chǔ)管理钮莲;capacity等于數(shù)組長度葡公,當(dāng)Vector數(shù)組不夠用時(shí)擴(kuò)容,擴(kuò)容大小默認(rèn)是capacityIncrement(如果該參數(shù)為0則當(dāng)前數(shù)組長度*2處理)莫秆。
    @Test
    public void testCapacity() {
        //Vector擴(kuò)容是在內(nèi)部數(shù)組放滿之后調(diào)用grow
        //擴(kuò)容方式分2種:1.數(shù)組容量*2處理;2.數(shù)組容量變?yōu)閚ewCapacity=oldCapacity+capacityIncrement
        Vector v1 = new Vector(1);
        Vector v2 = new Vector(1, 1);//如果設(shè)置capacityIncrement則按照第二種方式擴(kuò)容
        System.out.println("v1 capacity:" + v1.capacity() + "|v2 capacity:" + v2.capacity());
        v1.add("1");
        v2.add("1");
        v1.add("2");
        v2.add("2");
        System.out.println("v1 capacity:" + v1.capacity() + "|v2 capacity:" + v2.capacity());
        v1.add("3");
        v2.add("3");
        System.out.println("v1 capacity:" + v1.capacity() + "|v2 capacity:" + v2.capacity());
    }

運(yùn)行結(jié)果:

v1 capacity:1|v2 capacity:1
v1 capacity:2|v2 capacity:2
v1 capacity:4|v2 capacity:3

v1间雀、v2初始容量capacity均為1,v2設(shè)置capacityIncrement為1镊屎;v1每次擴(kuò)容為原來容量1倍惹挟,v2每次擴(kuò)容capacityIncrement大小。

    private void grow(int minCapacity) {//擴(kuò)容方法源代碼
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //根據(jù)capacityIncrement是否存在選擇擴(kuò)容方式
        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);
    }
  1. Vector數(shù)組容量可以?自動(dòng)擴(kuò)容和手動(dòng)縮容以便適應(yīng)Vector創(chuàng)建之后?數(shù)組大小變化。
    @Test
    public void testCapcityIncrementAndReduce() {
        Vector v1 = new Vector(0, 10);
        System.out.println("v1 capcity:" + v1.capacity());
        v1.add("1");
        System.out.println("v1 capcity:" + v1.capacity());
        v1.trimToSize();
        System.out.println("v1 capcity:" + v1.capacity());
    }

運(yùn)行結(jié)果:

v1 capcity:0
v1 capcity:10
v1 capcity:1
    public synchronized boolean add(E e) {//add方法源代碼
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }
    public synchronized void trimToSize() {//縮容源代碼
        modCount++;
        int oldCapacity = elementData.length;
        if (elementCount < oldCapacity) {
            elementData = Arrays.copyOf(elementData, elementCount);
        }
    }

可以通過trimToSize方法減少Vector所占用空間。

  1. 如果在Vector集合迭代時(shí)集合中添加或刪除元素(數(shù)組結(jié)構(gòu)改變了)榴徐,Vector迭代器迭代會(huì)fail-fast(快速失敗)财剖,迭代方法拋出ConcurrentModificationException異常。
    @Test
    public void testFailFast() throws InterruptedException {
        //fail-fast 當(dāng)遍歷Iterator對(duì)象時(shí)如果此時(shí)對(duì)數(shù)組做增/刪操作,拋出異常
        Vector v1 = new Vector();
        v1.add("a");
        v1.add("b");
        v1.add("c");
        Iterator it = v1.iterator();
        new Thread(() -> {
            try {
                Thread.sleep(1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            v1.remove("c");
            System.out.println("v1 remove one element");
        }).start();
        while (it.hasNext()) {
            Object next = it.next();
            System.out.println("v1:" + next);
            Thread.sleep(3000l);
        }
    }

運(yùn)行結(jié)果:

v1:a
v1 remove one element
java.util.ConcurrentModificationException

當(dāng)正在迭代v1時(shí),我們v1做刪除或添加操作,拋出異常。

        final void checkForComodification() {//modCount在每次對(duì)象結(jié)果變化時(shí)+1
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

避免出現(xiàn)該問題方法:

    @Test
    public void testClone() throws InterruptedException {
        //假設(shè)有多個(gè)線程同時(shí)操作一個(gè)Vector對(duì)象,如果此時(shí)需要對(duì)Vector遍歷,需要先clone該對(duì)象,這樣就能避免在迭代時(shí)其他線程操作對(duì)象導(dǎo)致迭代失敗
        //Vector是線程安全的
        Vector v1 = new Vector();
        v1.add("a");
        v1.add("b");
        v1.add("c");
        Vector v2 = (Vector) v1.clone();
        Iterator it = v1.iterator();
        new Thread(() -> {
            try {
                Thread.sleep(1000l);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            v2.remove("c");
            System.out.println("v2 remove");
        }).start();
        while (it.hasNext()) {
            Object next = it.next();
            System.out.println("v1:" + next);
            Thread.sleep(3000l);
        }
    }

運(yùn)行結(jié)果:

v1:a
v2 remove
v1:b
v1:c

當(dāng)我們要迭代一個(gè)v1時(shí)先調(diào)用clone()方法克隆出v2驳规,對(duì)v2迭代。

    public synchronized Object clone() {
        try {
            @SuppressWarnings("unchecked")
                Vector<E> v = (Vector<E>) super.clone();
            v.elementData = Arrays.copyOf(elementData, elementCount);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
  1. Vector是線程安全的署海;如果不需要線程安全吗购,可以使用ArrayList代替Vector医男。
public synchronized void addElement(E obj) {}
public synchronized boolean removeElement(Object obj) {}
public synchronized void removeAllElements() {}
...

方法加上synchronized關(guān)鍵字來保證線程之間同步。


代碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捻勉,一起剝皮案震驚了整個(gè)濱河市镀梭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌踱启,老刑警劉巖报账,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異埠偿,居然都是意外死亡透罢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門冠蒋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來羽圃,“玉大人,你說我怎么就攤上這事抖剿⌒嗄” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵斩郎,是天一觀的道長脑融。 經(jīng)常有香客問我,道長缩宜,這世上最難降的妖魔是什么肘迎? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮脓恕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窿侈。我一直安慰自己炼幔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布史简。 她就那樣靜靜地躺著乃秀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪圆兵。 梳的紋絲不亂的頭發(fā)上跺讯,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音殉农,去河邊找鬼刀脏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛超凳,可吹牛的內(nèi)容都是我干的愈污。 我是一名探鬼主播耀态,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼暂雹!你這毒婦竟也來了首装?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤杭跪,失蹤者是張志新(化名)和其女友劉穎仙逻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涧尿,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡系奉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了现斋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片喜最。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖庄蹋,靈堂內(nèi)的尸體忽然破棺而出瞬内,到底是詐尸還是另有隱情,我是刑警寧澤限书,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布虫蝶,位于F島的核電站,受9級(jí)特大地震影響倦西,放射性物質(zhì)發(fā)生泄漏能真。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一扰柠、第九天 我趴在偏房一處隱蔽的房頂上張望粉铐。 院中可真熱鬧,春花似錦卤档、人聲如沸蝙泼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽汤踏。三九已至,卻和暖如春舔腾,著一層夾襖步出監(jiān)牢的瞬間溪胶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工稳诚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哗脖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像懒熙,于是被迫代替她去往敵國和親丘损。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容