Vector源碼分析

Collection家族成員關(guān)系圖

在上圖中可以看到焙糟,VectorArrayList在繼承關(guān)系中是平輩關(guān)系,可以簡單的理解Vector就是線程安全的ArrayList。本文將從源碼角度分析Vector,如需了解ArrayListLinkedList可點擊ArrayList與LinkedList源碼分析-從源碼角度分析數(shù)組與鏈表的區(qū)別汽烦。


繼承關(guān)系

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

構(gòu)造函數(shù)

    public Vector() {
        this(10);
    }

無參構(gòu)造調(diào)用int參數(shù)構(gòu)造鸿捧,initialCapacity=10

    public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }

int參數(shù)構(gòu)造會調(diào)用兩個int類型參數(shù)構(gòu)造 initialCapacity = 10 , capacityIncrement = 0

    protected Object[] elementData;
    public Vector(int initialCapacity, int capacityIncrement) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
        this.capacityIncrement = capacityIncrement;
    }

當(dāng)initialCapacity沒有指定時屹篓,將實例化一個長度10的Object數(shù)組,這點與ArrayList類似匙奴。

    public Vector(Collection<? extends E> c) {
        elementData = c.toArray();
        elementCount = elementData.length;
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
    }

c.toArray()得到Object[]或者泛型數(shù)組堆巧,是Object[]直接賦值,,如果是泛型數(shù)組泼菌,將轉(zhuǎn)為Object[]再賦值谍肤。


add(E e)

    public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

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

    private void grow(int minCapacity) {
        int oldCapacity = elementData.length;
        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);
    }

可以看到Vectoradd方法和它的同門兄弟ArrayListadd方法的邏輯是一樣的,但是有一些小的差別

  • 1.使用synchronized修飾哗伯,線程安全
  • 2.擴容大小在沒有指定時是原大小的2倍進行擴容荒揣,而ArrayList的擴容大小是加上原大小的>>1,也就是1.5倍進行擴容

add(int index, E element)

    public void add(int index, E element) {
        insertElementAt(element, index);
    }

    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++;
    }

insertElementAt(E obj, int index)使用synchronized修飾,線程安全焊刹,主要邏輯

  • 1.修改次數(shù)++
  • 2.判斷是否需要擴容系任,需要則擴容
  • 3.index后的元素通過copy到一個新的數(shù)組整體后移1位
  • 4.對index索引進行賦值
  • 5.元素數(shù)量++

重點分析下copy數(shù)組然后右移的邏輯
System.arraycopy()方法是一個原生的靜態(tài)方法,用于從源數(shù)組拷貝元素到目標(biāo)數(shù)組中
System.arraycopy() 方法如下:

public static native void arraycopy(Object src, int srcPos,Object dest, int destPos,
int length);

src: 源數(shù)組 .
srcPos: 源數(shù)組中開始拷貝的索引值
dest: 目標(biāo)數(shù)組
destPos: 拷貝到目標(biāo)數(shù)組開始的索引值
length: 拷貝元素的個數(shù)
add(int index, E element)就是將index后面的數(shù)組copy了一份虐块,并將index后的索引值加1俩滥,然后將數(shù)組index索引賦值。


remove(int index)

public synchronized E remove(int index) {
        modCount++;
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);
        E oldValue = elementData(index);

        int numMoved = elementCount - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--elementCount] = null; 

        return oldValue;
    }
  • 1.synchronized關(guān)鍵字修飾贺奠,線程安全
  • 2.numMoved表示要左移的元素霜旧,是否是大于0,大于0則將index后的元素左移一個位置儡率,并將最后一個索引的最后一個元素置空挂据。如果等于0以清,說明是index最后一個元素的索引,不需要左移棱貌,直接將最后一個索引置空玖媚。

remove(Object o)

    public boolean remove(Object o) {
        return removeElement(o);
    }

    public synchronized boolean removeElement(Object obj) {
        modCount++;
        int i = indexOf(obj);
        if (i >= 0) {
            removeElementAt(i);
            return true;
        }
        return false;
    }

    public int indexOf(Object o) {
        return indexOf(o, 0);
    }

    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;
    }

remove(Object o)remove(int index)多了遍歷對比元素獲取索引的步驟,其他一樣婚脱。


總結(jié)

  • 1.VectorArrayList的底層實現(xiàn)都是Object[]
  • 2.Vector線程安全今魔,ArrayList非線程安全
  • 3.Vector默認(rèn)2倍大小擴容,ArrayList1.5倍大小進行擴容
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末障贸,一起剝皮案震驚了整個濱河市错森,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌篮洁,老刑警劉巖涩维,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異袁波,居然都是意外死亡瓦阐,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門篷牌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睡蟋,“玉大人,你說我怎么就攤上這事枷颊〈辽保” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵夭苗,是天一觀的道長信卡。 經(jīng)常有香客問我,道長题造,這世上最難降的妖魔是什么傍菇? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮晌梨,結(jié)果婚禮上桥嗤,老公的妹妹穿的比我還像新娘。我一直安慰自己仔蝌,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布荒吏。 她就那樣靜靜地躺著敛惊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绰更。 梳的紋絲不亂的頭發(fā)上瞧挤,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天锡宋,我揣著相機與錄音,去河邊找鬼特恬。 笑死执俩,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的癌刽。 我是一名探鬼主播役首,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼显拜!你這毒婦竟也來了衡奥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤远荠,失蹤者是張志新(化名)和其女友劉穎矮固,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體譬淳,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡档址,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了邻梆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片守伸。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖确虱,靈堂內(nèi)的尸體忽然破棺而出含友,到底是詐尸還是另有隱情,我是刑警寧澤校辩,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布窘问,位于F島的核電站,受9級特大地震影響宜咒,放射性物質(zhì)發(fā)生泄漏惠赫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一故黑、第九天 我趴在偏房一處隱蔽的房頂上張望儿咱。 院中可真熱鬧,春花似錦场晶、人聲如沸混埠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钳宪。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吏颖,已是汗流浹背搔体。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留半醉,地道東北人疚俱。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像缩多,于是被迫代替她去往敵國和親呆奕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348