Java集合3:List,AbstractList和ArrayList

List

List是一個(gè)有序集合的接口,自然就相比Collection來(lái)說(shuō)就添加了一些和索引有關(guān)的方法:

void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);
default void sort(Comparator<? super E> c);
E get(int index);
E set(int index, E element);
E remove(int index);
int indexOf(Object o);      //若未找到則返回-1
int lastIndexOf(Object o);  //若未找到則返回-1

以及一些其他獨(dú)有的方法:

ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
default void replaceAll(UnaryOperator<E> operator)
List<E> subList(int fromIndex, int toIndex);

值得一提的是坞淮,在Java 9之后還出了一堆靜態(tài)方法,它們是用來(lái)創(chuàng)建不可修改的List的(也就是生成對(duì)象以后就不能新增和修改其中的元素了)

static <E> List<E> of()
static <E> List<E> of(E e1)
static <E> List<E> of(E e1, E e2)
...
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
static <E> List<E> of(E... elements)

AbstractList

AbstractColletion類似陪捷,它也是系統(tǒng)提供的一個(gè)List接口的骨干實(shí)現(xiàn)回窘,為了減輕程序員的工作量。如果要實(shí)現(xiàn)不可修改元素的列表市袖,繼承它并實(shí)現(xiàn)get(int)size()方法即可啡直。若要實(shí)現(xiàn)可修改元素的列表,還需要實(shí)現(xiàn)set(int, E)add(int, E)remove(int)方法 (如果是長(zhǎng)度不可變的列表的話后兩個(gè)方法也可以不實(shí)現(xiàn))付枫。

它繼承自AbstractColletion烹玉,也就是說(shuō)它將AbstractColletion里的iterator方法給實(shí)現(xiàn)了,不過(guò)這個(gè)方法在本系列第一講中就已經(jīng)介紹過(guò)了hhhh

然后它也實(shí)現(xiàn)了List接口,將大部分方法給實(shí)現(xiàn)了兔跌。
這些方法都比較簡(jiǎn)單擎析,值得一提的是subList方法:

public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size());
    return (this instanceof RandomAccess ?
            new RandomAccessSubList<>(this, fromIndex, toIndex) :
            new SubList<>(this, fromIndex, toIndex));
}

根據(jù)名字就知道這是用來(lái)生產(chǎn)子列表的。
這里先進(jìn)行防越界檢查事示,然后就是判斷是不是RandomAccess接口的實(shí)例(這個(gè)接口,根據(jù)文檔解釋,就是用來(lái)表示某個(gè)列表是否支持隨機(jī)訪問(wèn)装获,而不是只支持順序訪問(wèn)),然后再生成SubList的對(duì)象厉颤。
SubList是個(gè)內(nèi)部類穴豫,繼承自AbstractList
構(gòu)造函數(shù)有兩個(gè):

    /**
     * Constructs a sublist of an arbitrary AbstractList, which is
     * not a SubList itself.
     */
    public SubList(AbstractList<E> root, int fromIndex, int toIndex) {
        this.root = root;
        this.parent = null;
        this.offset = fromIndex;
        this.size = toIndex - fromIndex;
        this.modCount = root.modCount;
    }

    /**
     * Constructs a sublist of another SubList.
     */
    protected SubList(SubList<E> parent, int fromIndex, int toIndex) {
        this.root = parent.root;
        this.parent = parent;
        this.offset = parent.offset + fromIndex;
        this.size = toIndex - fromIndex;
        this.modCount = root.modCount;
    }

分別是用List來(lái)生成SubList,以及用SubList來(lái)生成SubList逼友,支持多層嵌套精肃,也就是說(shuō)SubList的SubList的SubList...這種都可以。還可以看出root是指最最上層的根List帜乞,而parent則是比自己高一級(jí)的SubList司抱。

仔細(xì)看一下其他方法:

public E set(int index, E element) {
    Objects.checkIndex(index, size);
    checkForComodification();
    return root.set(offset + index, element);
}

public E get(int index) {
    Objects.checkIndex(index, size);
    checkForComodification();
    return root.get(offset + index);
}

public void add(int index, E element) {
    rangeCheckForAdd(index);
    checkForComodification();
    root.add(offset + index, element);
    updateSizeAndModCount(1);
}

public E remove(int index) {
    Objects.checkIndex(index, size);
    checkForComodification();
    E result = root.remove(offset + index);
    updateSizeAndModCount(-1);
    return result;
}

可以看出這里的各種增刪查改都是通過(guò)調(diào)用根列表的增刪查改實(shí)現(xiàn)的。除此之外黎烈,在所有操作之前都有調(diào)用checkForComodification方法习柠,這是不是和Iterator里的很相似hhh
不過(guò)這里是判斷自己的modCount和根列表的modCount是否相等:

private void checkForComodification() {
    if (root.modCount != this.modCount)
    throw new ConcurrentModificationException();
}

它的作用也和iterator里的一樣,為了避免外部類偷偷修改了數(shù)組元素的個(gè)數(shù)照棋,從而導(dǎo)致內(nèi)部類中size屬性無(wú)法得到更新從而出錯(cuò)资溃。
既然如此,那在內(nèi)部類中修改了數(shù)組個(gè)數(shù)之后就需要對(duì)modCount進(jìn)行更新了烈炭,這在updateSizeAndModCount方法中有具體實(shí)現(xiàn):

private void updateSizeAndModCount(int sizeChange) {
    SubList<E> slist = this;
    do {
        slist.size += sizeChange;
        slist.modCount = root.modCount;
        slist = slist.parent;
    } while (slist != null);
}

大致上來(lái)說(shuō)就是一直往上尋找自己的上一級(jí)SubList溶锭,把他們的modCount和size都給更新了,這樣下次調(diào)用checkForComodification就不會(huì)拋出錯(cuò)誤了梳庆。


ArrayList

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末暖途,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膏执,更是在濱河造成了極大的恐慌驻售,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件更米,死亡現(xiàn)場(chǎng)離奇詭異欺栗,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門迟几,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)消请,“玉大人,你說(shuō)我怎么就攤上這事类腮‰” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵蚜枢,是天一觀的道長(zhǎng)缸逃。 經(jīng)常有香客問(wèn)我,道長(zhǎng)厂抽,這世上最難降的妖魔是什么需频? 我笑而不...
    開封第一講書人閱讀 58,755評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮筷凤,結(jié)果婚禮上昭殉,老公的妹妹穿的比我還像新娘。我一直安慰自己藐守,他們只是感情好挪丢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吗伤,像睡著了一般吃靠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上足淆,一...
    開封第一講書人閱讀 51,610評(píng)論 1 305
  • 那天巢块,我揣著相機(jī)與錄音,去河邊找鬼巧号。 笑死族奢,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丹鸿。 我是一名探鬼主播越走,決...
    沈念sama閱讀 40,352評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼靠欢!你這毒婦竟也來(lái)了廊敌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤门怪,失蹤者是張志新(化名)和其女友劉穎骡澈,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掷空,經(jīng)...
    沈念sama閱讀 45,717評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肋殴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評(píng)論 3 336
  • 正文 我和宋清朗相戀三年囤锉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片护锤。...
    茶點(diǎn)故事閱讀 40,021評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡官地,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烙懦,到底是詐尸還是另有隱情驱入,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評(píng)論 5 346
  • 正文 年R本政府宣布修陡,位于F島的核電站沧侥,受9級(jí)特大地震影響可霎,放射性物質(zhì)發(fā)生泄漏魄鸦。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評(píng)論 3 330
  • 文/蒙蒙 一癣朗、第九天 我趴在偏房一處隱蔽的房頂上張望拾因。 院中可真熱鬧,春花似錦旷余、人聲如沸绢记。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蠢熄。三九已至,卻和暖如春炉旷,著一層夾襖步出監(jiān)牢的瞬間签孔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工窘行, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留饥追,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,224評(píng)論 3 371
  • 正文 我出身青樓罐盔,卻偏偏與公主長(zhǎng)得像但绕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惶看,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評(píng)論 2 355

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