jdk1.8源碼解析-ArrayList

ArrayList

本文原創(chuàng)地址伤提,我的博客https://jsbintask.cn/2019/03/22/jdk/jdk8-arraylist/(食用效果最佳),轉(zhuǎn)載請(qǐng)注明出處!

前言

ArrayList是一個(gè)長(zhǎng)度可調(diào)節(jié)的數(shù)組认烁,使用者只需向其中添加肿男,刪除介汹,獲取元素,可以向其中添加任何對(duì)象(包括null值)舶沛,無(wú)需關(guān)系它的擴(kuò)容嘹承,,縮減問(wèn)題如庭。它實(shí)現(xiàn)了list接口所有方法,它基本等價(jià)于Vector豪娜,唯一不同的是它沒(méi)有任何同步手段哟楷,多線程環(huán)境須慎重考慮否灾。

ArrayList結(jié)構(gòu)

類關(guān)系

ArrayList

這里唯一需要注意的是墨技,它實(shí)現(xiàn)了一個(gè)RandomAccess接口,這個(gè)接口沒(méi)有任何方法聲明断楷,是一個(gè)標(biāo)記接口崭别,它是為了告訴使用者如果實(shí)現(xiàn)了這個(gè)接口那么你的實(shí)現(xiàn)在算法上應(yīng)該for循環(huán)會(huì)比使用iterator更快,LinkedList則沒(méi)有實(shí)現(xiàn)這個(gè)接口舞痰,它則是iterator更快诀姚。
我們查看Collections工具類二分搜索方法:
ArrayList

這就驗(yàn)證了我們上面說(shuō)的那句話,實(shí)現(xiàn)了這個(gè)接口的子類在隨機(jī)訪問(wèn)時(shí)會(huì)更快(for循環(huán))呀打,而沒(méi)有實(shí)現(xiàn)糯笙,則順序訪問(wèn)會(huì)更加快(iterator迭代)。

類結(jié)構(gòu)

ArrayList

它內(nèi)部主要有兩個(gè)成員變量瘫寝,elementData用于存儲(chǔ)數(shù)據(jù),size用于標(biāo)記存儲(chǔ)了多少個(gè)元素咪啡,size總是按最大值顯示的(考慮多線程環(huán)境暮屡,添加元素先增加size)。

方法解析

add(E e) 末尾插入新元素

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  //判斷是否需要擴(kuò)容
    elementData[size++] = e;
    return true;
}
  1. 首先進(jìn)行了擴(kuò)容准夷,最終調(diào)用的是grow方法:


    ArrayList

    從這里我們知道每次擴(kuò)容后的大小為原來(lái)的容量 n + n/2莺掠,例如原來(lái)的容量是10,擴(kuò)容后的容量則成了15.

  2. 將新元素放到了原來(lái)的元素的后面楔绞,因?yàn)椴挥靡苿?dòng)原來(lái)的元素唇兑,所以比較快。

add(int index, E e) 指定位置插入新元素

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

    ensureCapacityInternal(size + 1);  // Increments modCount!!
    System.arraycopy(elementData, index, elementData, index + 1,
                     size - index);
    elementData[index] = element;
    size++;
}
  1. 檢查index位置是否合理(太小蔫耽,太大)
  2. 同上匙铡,檢查是否需要擴(kuò)大數(shù)組容量香伴。
  3. 將原來(lái)index后面的所有元素往后面移動(dòng)一個(gè)位置,這樣index位置就空出來(lái)了具帮。
  4. 將新元素放到index位置,接著size加1
    從這里我們知道蜂厅,因?yàn)槊看尾迦攵夹枰苿?dòng)index后面的元素膊畴,所以效率很低,盡量避免使用該方法稠通。其它的add方法同上類似,這里不再贅述改橘。

get(int index)

public E get(int index) {
    rangeCheck(index);

    return elementData(index);
}

獲取指定位置元素,直接返回?cái)?shù)組對(duì)應(yīng)的位置狮惜,不需要額外操作碌识,很快!(這也是為什么它能夠?qū)崿F(xiàn)了AccessRandom)

remove(int index)

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}
  1. 直接移動(dòng)index后面的所有元素向前移動(dòng)开泽,覆蓋index位置眼姐,簡(jiǎn)單粗暴。 從這里我們知道需要移動(dòng)數(shù)組,效率并不高罢杉。

index(E e) 查詢?cè)匚恢?/p>

public int indexOf(Object o) {
    if (o == null) {
        for (int i = 0; i < size; i++)
            if (elementData[i]==null)
                return i;
    } else {
        for (int i = 0; i < size; i++)
            if (o.equals(elementData[i]))
                return i;
    }
    return -1;
}
  1. 遍歷查找第一個(gè)equals要找的的元素的位置滩租,返回,簡(jiǎn)單粗暴猎莲。
    最后我們介紹下另一個(gè)方法trimToSize():
public void trimToSize() {
    modCount++;
    if (size < elementData.length) {
        elementData = (size == 0)
          ? EMPTY_ELEMENTDATA
          : Arrays.copyOf(elementData, size);
    }
}

這個(gè)方法是用來(lái)縮減空間的技即,當(dāng)你的ArrayList裝的東西已經(jīng)確定以后(以后不會(huì)再刪除,添加)身笤,可以調(diào)用這個(gè)方法節(jié)省內(nèi)存空間葵陵。 它會(huì)把數(shù)組的長(zhǎng)度縮減得和size一樣。

總結(jié)

  1. ArrayList內(nèi)部使用一個(gè)數(shù)組存儲(chǔ)數(shù)據(jù)娇钱,使用一個(gè)size變量標(biāo)記儲(chǔ)存了多少個(gè)元素。
  2. 它可以存儲(chǔ)任一對(duì)象文搂,包括null,當(dāng)向其中添加元素時(shí)细疚,會(huì)進(jìn)行擴(kuò)容操作,每次擴(kuò)容增加的大小為原來(lái)數(shù)組長(zhǎng)度的一半然遏。所以最好使用之前能夠估計(jì)好元素的數(shù)量吧彪。
  3. 查找元素,末尾插入元素很快秧倾,指定位置插入元素傀缩,移除元素效率很低,因?yàn)樾枰苿?dòng)數(shù)組售淡。 所以查找操作多推薦使用ArrayList,刪除操作多時(shí)推薦使用LinkedList揖闸。
  4. 可以調(diào)用trimToSize”瘦身“料身。
  5. 繼承了一個(gè)AccessRandom標(biāo)記接口,繼承者在算法實(shí)現(xiàn)上應(yīng)該考慮for循環(huán)遍歷元素要快于iterator遍歷贮泞。
    關(guān)注我祟牲,這里只有干貨!
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末议惰,一起剝皮案震驚了整個(gè)濱河市乡恕,隨后出現(xiàn)的幾起案子俯萎,更是在濱河造成了極大的恐慌运杭,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撇眯,死亡現(xiàn)場(chǎng)離奇詭異虱咧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)玄坦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門煎楣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人择懂,你說(shuō)我怎么就攤上這事另玖。” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵绑榴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我窃诉,道長(zhǎng)赤套,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任宣脉,我火速辦了婚禮剔氏,結(jié)果婚禮上竹祷,老公的妹妹穿的比我還像新娘塑陵。我一直安慰自己蜡励,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布兼都。 她就那樣靜靜地躺著占遥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芬萍。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,692評(píng)論 1 305
  • 那天柬祠,我揣著相機(jī)與錄音漫蛔,去河邊找鬼。 笑死莽龟,一個(gè)胖子當(dāng)著我的面吹牛禁炒,可吹牛的內(nèi)容都是我干的塑煎。 我是一名探鬼主播障癌,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼塘慕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼益缠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起幅慌,我...
    開(kāi)封第一講書(shū)人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎迄靠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體雨席,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡陡厘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年特占,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片是目。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡懊纳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出嗤疯,到底是詐尸還是另有隱情,我是刑警寧澤茂缚,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布脚囊,位于F島的核電站,受9級(jí)特大地震影響翩蘸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一扶踊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧备籽,春花似錦、人聲如沸霉猛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)伏嗜。三九已至,卻和暖如春承绸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轩猩。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工均践, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衔瓮,地道東北人浊猾。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓葫慎,卻偏偏與公主長(zhǎng)得像薇宠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子澄港,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355