Java8 ArraysList擴(kuò)容過(guò)程分析

在調(diào)用add(E e)時(shí),會(huì)調(diào)用ensureCapacityInternal(size + 1)來(lái)確保數(shù)組有足夠的容量來(lái)新增元素端考。

    public boolean add(E e) {
        ensureCapacityInternal(size + 1); 
        elementData[size++] = e;
        return true;
    }

ensureCapacityInternal(int mincapacity)源碼如下弛房,該方法調(diào)用了calculateCapacity(elementData, minCapacity)ensureExplicitCapacity

    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }

其中calculateCapacity(elementData, minCapacity)源碼如下

    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        // 調(diào)用ArrayList的無(wú)參構(gòu)造函數(shù)开睡,elementData會(huì)指向這個(gè)DEFAULTCAPACITY_EMPTY_ELEMENTDATA空數(shù)組,
        // 這時(shí)如果調(diào)用add就會(huì)進(jìn)入下面這個(gè)判斷
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }

如果當(dāng)前數(shù)組為空數(shù)組(剛使用無(wú)參構(gòu)造函數(shù)創(chuàng)建完ArrayList鞭呕,往其添加元素時(shí))蛤育,則返回10,即最小的容量是10(剛創(chuàng)建完ArrayList葫松,第一次擴(kuò)容要求capacity最小是10)瓦糕。
ensureExplicitCapacity(int minCapacity)源碼如下,大概邏輯是:如果當(dāng)前數(shù)組長(zhǎng)度達(dá)不到想要的minCapacity腋么,則調(diào)用grow擴(kuò)容

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
        // 如果要求的最小容量比當(dāng)前數(shù)組長(zhǎng)度大咕娄,即當(dāng)前數(shù)組長(zhǎng)度放不下了,就會(huì)調(diào)用grow擴(kuò)容
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

grow(int minCapacity)大概邏輯:計(jì)算新的數(shù)組長(zhǎng)度珊擂,為原來(lái)數(shù)組長(zhǎng)度的1.5倍圣勒,如果該值比要求的minCapacity小费变,則取minCapacity。
如果新數(shù)組長(zhǎng)度比MAX_ARRAY_SIZE大圣贸,則調(diào)用hugeCapacity獲取一個(gè)長(zhǎng)度挚歧。
最后調(diào)用Arrays.copyOf(elementData, newCapacity)創(chuàng)建新數(shù)組并拷貝元素過(guò)去。
源碼如下

    private void grow(int minCapacity) {
        // 舊的數(shù)組長(zhǎng)度
        int oldCapacity = elementData.length;
        // >> 1是 右移一位吁峻,即除以2滑负。所以這句代碼意思是:newCapacity是oldCapacity的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        // 如果newCapacity比minCapacity還要小(剛創(chuàng)建完ArrayList用含,往其添加元素時(shí)會(huì)滿足這種情況)矮慕,則取minCapacity
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        // 如果newCapacity比數(shù)組最大值MAX_ARRAY_SIZE大,則調(diào)用hugeCapacity獲取一個(gè)比較大的capacity
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // 創(chuàng)建一個(gè)newCapacity大小的新數(shù)組啄骇,并將原來(lái)數(shù)組的元素拷貝過(guò)去
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

hugeCapacity(int minCapacity)大概邏輯:如果minCapacity比MAX_ARRAY_SIZE(Integer.MAX_VALUE-8)大痴鳄,則取Integer.MAX_VALUE,否則取MAX_ARRAY_SIZE缸夹。
源碼如下

    private static int hugeCapacity(int minCapacity) {
        // minCapacity小于0表示溢出超過(guò)int能表示的數(shù)字范圍
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        // 如果minCapacity大于MAX_ARRAY_SIZE(Integer.MAX_VALUE-8),則取nteger.MAX_VALUE夏跷,否則取MAX_ARRAY_SIZE(Integer.MAX_VALUE-8)
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市明未,隨后出現(xiàn)的幾起案子槽华,更是在濱河造成了極大的恐慌,老刑警劉巖趟妥,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件猫态,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡披摄,警方通過(guò)查閱死者的電腦和手機(jī)亲雪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)疚膊,“玉大人义辕,你說(shuō)我怎么就攤上這事≡⒌粒” “怎么了灌砖?”我有些...
    開(kāi)封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)傀蚌。 經(jīng)常有香客問(wèn)我基显,道長(zhǎng),這世上最難降的妖魔是什么善炫? 我笑而不...
    開(kāi)封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任撩幽,我火速辦了婚禮,結(jié)果婚禮上箩艺,老公的妹妹穿的比我還像新娘窜醉。我一直安慰自己宪萄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布榨惰。 她就那樣靜靜地躺著拜英,像睡著了一般。 火紅的嫁衣襯著肌膚如雪读串。 梳的紋絲不亂的頭發(fā)上聊记,一...
    開(kāi)封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天撒妈,我揣著相機(jī)與錄音恢暖,去河邊找鬼。 笑死狰右,一個(gè)胖子當(dāng)著我的面吹牛杰捂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播棋蚌,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼嫁佳,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了谷暮?” 一聲冷哼從身側(cè)響起蒿往,我...
    開(kāi)封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎湿弦,沒(méi)想到半個(gè)月后瓤漏,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體松忍,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡孝赫,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年乖阵,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了递沪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霞玄。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡歼秽,死狀恐怖盐固,靈堂內(nèi)的尸體忽然破棺而出妹孙,到底是詐尸還是另有隱情罗标,我是刑警寧澤庸队,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站闯割,受9級(jí)特大地震影響皿哨,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纽谒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一证膨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鼓黔,春花似錦央勒、人聲如沸不见。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)稳吮。三九已至,卻和暖如春井濒,著一層夾襖步出監(jiān)牢的瞬間灶似,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工瑞你, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酪惭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓者甲,卻偏偏與公主長(zhǎng)得像春感,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子虏缸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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