Java 1.8 ArrayList 源碼分析

我們聲明一個初始容量為1的ArrayList〉肃冢看看在add時候到底發(fā)生了什么。

public class Main {
    public static void main(String[] args) {
        final ArrayList<String> objects = new ArrayList<>(1);
        objects.add("A");
        objects.add("B");
        objects.add("C");
    }
}

當(dāng)聲明的容量小于10時的情況

執(zhí)行第一個語句objects.add("A"),此時size是0捶码,執(zhí)行ensureCapacityInternal(1)。

private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

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

calculateCapacity(elementData,1)或链,此時數(shù)組為空惫恼,所以return 10。調(diào)用ensureExplicitCapacity(10)澳盐。

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}

10 > 0 調(diào)用grow(10)

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

newCapacity - minCapacity = -10 < 0 ,所以newCapacity=10祈纯。elementData = Arrays.copyOf(elementData,10); elementData容量變?yōu)榱?0。

private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

無需擴容的情況

接下來執(zhí)行objects.add("B")叼耙。此時size是1腕窥,執(zhí)行ensureCapacityInternal(2)。

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

calculateCapacity(elementData,2)筛婉,此時數(shù)組不為空簇爆,所以return 2。調(diào)用ensureExplicitCapacity(2)。

private void ensureCapacityInternal(int minCapacity) {
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private static int calculateCapacity(Object[] elementData, int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}

2-10 < 0 所以不需要grow入蛆,直接執(zhí)行上面的elementData[size++] = e响蓉。

private void ensureExplicitCapacity(int minCapacity) {
    modCount++;

    // overflow-conscious code
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}

正常擴容情況

1.5倍擴容,將原來的數(shù)組整個拷貝過去安寺。

int newCapacity = oldCapacity + (oldCapacity >> 1);
elementData = Arrays.copyOf(elementData, newCapacity)

總結(jié)

  • 當(dāng)我們new一個ArrayList的時候厕妖,初始容量為0,內(nèi)部表示為一個空數(shù)組挑庶。在一次add后言秸,容量為擴充為10。
  • 我們可以自定義初始容量的大小迎捺,值得注意的是举畸,如果定義的容量小于10,在第一次add后凳枝,容量會擴充為10抄沮。
  • 容量不夠時,按照1.5倍原容量大小擴容岖瑰,復(fù)制原容量數(shù)組的所有元素到新容量的數(shù)組去叛买。所以說擴容是一個比較昂貴的操作。我們可以根據(jù)需求設(shè)置初始容量蹋订。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末率挣,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子露戒,更是在濱河造成了極大的恐慌椒功,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件智什,死亡現(xiàn)場離奇詭異动漾,居然都是意外死亡,警方通過查閱死者的電腦和手機荠锭,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門旱眯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人证九,你說我怎么就攤上這事键思。” “怎么了甫贯?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵吼鳞,是天一觀的道長。 經(jīng)常有香客問我叫搁,道長赔桌,這世上最難降的妖魔是什么供炎? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮疾党,結(jié)果婚禮上音诫,老公的妹妹穿的比我還像新娘。我一直安慰自己雪位,他們只是感情好竭钝,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著雹洗,像睡著了一般香罐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上时肿,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天庇茫,我揣著相機與錄音,去河邊找鬼螃成。 笑死旦签,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寸宏。 我是一名探鬼主播宁炫,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼氮凝!你這毒婦竟也來了羔巢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤覆醇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后炭臭,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體永脓,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年鞋仍,在試婚紗的時候發(fā)現(xiàn)自己被綠了常摧。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡威创,死狀恐怖落午,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情肚豺,我是刑警寧澤溃斋,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站吸申,受9級特大地震影響梗劫,放射性物質(zhì)發(fā)生泄漏享甸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一梳侨、第九天 我趴在偏房一處隱蔽的房頂上張望蛉威。 院中可真熱鬧,春花似錦走哺、人聲如沸蚯嫌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽择示。三九已至,卻和暖如春彼哼,著一層夾襖步出監(jiān)牢的瞬間对妄,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工敢朱, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剪菱,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓拴签,卻偏偏與公主長得像孝常,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蚓哩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

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