集合-ArrayList擴容機制

引言

ArrayList是基于數(shù)組所實現(xiàn)的徘铝。
眾所周知,數(shù)組是不能進行擴容操作的泵琳,而我們調(diào)用ArrayList的add()等方法時卻可以實現(xiàn)擴容操作哗总。

源碼

其內(nèi)部源碼主要經(jīng)歷以下步驟:

public boolean add(E e) {
  ensureCapacityInternal(size + 1); 
  elementData[size++] = e;
  return true;
}
  • 當我們調(diào)用add()時,系統(tǒng)會先調(diào)用ensureCapacityInternal(size+1)來確認ArrayList的內(nèi)部數(shù)組elementData是否有足夠空間容納size+1大小的數(shù)據(jù)脸候。
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    ensureExplicitCapacity(minCapacity);
}
  • ensureCapacityInternal()中穷娱,首先系統(tǒng)會先判定內(nèi)部數(shù)組elementData是否等于默認的空數(shù)組,如果是的話运沦,則取DEFAULT_CAPACITY(默認容量為10)與minCapacity的最大值(即ArrayList默認構造一個容量為10的空數(shù)組)泵额,然后調(diào)用ensureExplicitCapacity()確認是否需要擴容。
private void ensureExplicitCapacity(int minCapacity) {
    modCount++;
    if (minCapacity - elementData.length > 0)
        grow(minCapacity);
}
  • ensureExplicitCapacity()中携添,首先增加modCount數(shù)量(modCount是用來記錄ArrayList元素數(shù)目被修改的次數(shù))嫁盲,其次進行判定minCapacity是否超過了當前數(shù)組elementData的長度,超過了則調(diào)用grow()方法薪寓,進行數(shù)組擴容操作亡资。未超過則進行elementData[size++] = e賦值操作。
private void grow(int minCapacity) {
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    elementData = Arrays.copyOf(elementData, newCapacity);
}
  • grow()方法中向叉,可以看到newCapacity = oldCapacity + (oldCapacity >> 1)锥腻,即是新的數(shù)組長度為原數(shù)組長度的1.5倍,再與傳入的minCapacity大小進行比較母谎,取最大值瘦黑,如果超過了MAX_ARRAY_SIZE大小(值為Interger.MAX_VALUE - 8),調(diào)用hugeCapacity()方法奇唤,然后調(diào)用Arrays.copyOf()將數(shù)組擴容并復制到新數(shù)組幸斥。
總結

ArrayList實現(xiàn)擴容操作的機制,就是在超過elementData數(shù)組長度時咬扇,將數(shù)組擴容1.5倍甲葬,并調(diào)用Arrays.copyOf復制到新數(shù)組。而至于1.5倍的擴容懈贺,是因為不會導致每次進行add操作時就要頻繁進行擴容數(shù)組長度经窖,也不會過于浪費內(nèi)存空間。當然梭灿,如果我們能預知ArrayList的大小時画侣,我們應該調(diào)用ensureCapacity()方法來事先擴容數(shù)組長度,避免頻繁擴容影響性能堡妒。

public void ensureCapacity(int minCapacity) {
    int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
        ? 0
        : DEFAULT_CAPACITY;
    if (minCapacity > minExpand) {
        ensureExplicitCapacity(minCapacity);
    }
}
擴展知識
  • 數(shù)組也不能進行刪除操作配乱,而ArrayList中可以調(diào)用remove()等方法來實現(xiàn)刪除操作,實際上是先遍歷查找出對應的position,然后調(diào)用System.arraycopy()方法將數(shù)據(jù)復制到新數(shù)組搬泥,然后再將原position位置的數(shù)據(jù)置空桑寨,使gc回收其資源
  • 由于ArrayList上述擴容機制佑钾,ArrayList的size()方法并不是返回其內(nèi)部數(shù)組elementData的長度西疤,而是返回size變量size變量在調(diào)用add休溶、remove等方法的時候增加或減小其值,例如在add方法中扰她,在賦值操作中elementData[size++] = e;使size值加一兽掰。addAllremove等方法同理徒役。
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末孽尽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忧勿,更是在濱河造成了極大的恐慌杉女,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸳吸,死亡現(xiàn)場離奇詭異熏挎,居然都是意外死亡,警方通過查閱死者的電腦和手機晌砾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門坎拐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人养匈,你說我怎么就攤上這事哼勇。” “怎么了呕乎?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵积担,是天一觀的道長。 經(jīng)常有香客問我猬仁,道長帝璧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任逐虚,我火速辦了婚禮聋溜,結果婚禮上,老公的妹妹穿的比我還像新娘叭爱。我一直安慰自己撮躁,他們只是感情好,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布买雾。 她就那樣靜靜地躺著把曼,像睡著了一般杨帽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嗤军,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天注盈,我揣著相機與錄音,去河邊找鬼叙赚。 笑死老客,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的震叮。 我是一名探鬼主播胧砰,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼苇瓣!你這毒婦竟也來了尉间?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤击罪,失蹤者是張志新(化名)和其女友劉穎哲嘲,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體媳禁,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡眠副,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了损话。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片侦啸。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖丧枪,靈堂內(nèi)的尸體忽然破棺而出光涂,到底是詐尸還是另有隱情,我是刑警寧澤拧烦,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布忘闻,位于F島的核電站,受9級特大地震影響恋博,放射性物質(zhì)發(fā)生泄漏齐佳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一债沮、第九天 我趴在偏房一處隱蔽的房頂上張望炼吴。 院中可真熱鬧,春花似錦疫衩、人聲如沸硅蹦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽童芹。三九已至涮瞻,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間假褪,已是汗流浹背署咽。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留生音,地道東北人宁否。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像缀遍,于是被迫代替她去往敵國和親家淤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

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