詳解Java集合框架

簡(jiǎn)介

Java最初版本只實(shí)現(xiàn)了一些常用的數(shù)據(jù)結(jié)構(gòu)蒿辙,并提供了這些類(lèi)或接口Vector,Stack,Hashtable,BitSet,Enumeration接口來(lái)實(shí)現(xiàn)這些結(jié)構(gòu)匾七。

其中Enumeration接口提供了讓我們能枚舉任意容器元素的抽象機(jī)制汇恤。

特點(diǎn)

將集合的接口與實(shí)現(xiàn)分離

這一點(diǎn)我們可以從常見(jiàn)的隊(duì)列Queue的設(shè)計(jì)上看出來(lái)偶器,隊(duì)列的原則是尾部添加元素略号,在隊(duì)列的頭部刪除元素,可以看到Java的實(shí)現(xiàn)是首先定義了一個(gè)接口刻肄,里面定義了一些Queue的常用操作方法,

public interface Queue<E> extends Collection<E> {
    ...
    boolean add(E e);
    boolean offer(E e);
    E remove();
    ...
}

然后在根據(jù)不同的數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)隊(duì)列采够,通常情況下隊(duì)列使用兩種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)肄方,循環(huán)數(shù)組和鏈表,如下圖:

這樣在編程的時(shí)候只需要更換實(shí)現(xiàn)類(lèi)就可以輕松的切換所使用的數(shù)據(jù)結(jié)構(gòu)了蹬癌。

Collection

可以看到上面的Queue都繼承Collection权她,其實(shí)集合類(lèi)的都是繼承了他,他提供了幾個(gè)最基本的方法:

public interface Collection<E> extends Iterable<E> {
    boolean add(E e);
    Iterator<E> iterator();
}

當(dāng)然還有其他方法逝薪。

add:添加一個(gè)元素

iterator:返回一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象隅要。使用它可以很方便的訪問(wèn)集合中的元素。

Iterator

Iterator接口包含的方法:

public interface Iterator<E> {    
    boolean hasNext();
 
    E next();

    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

遍歷元素的方式通過(guò)反復(fù)調(diào)用next方法即可訪問(wèn)每個(gè)元素董济,但是如果達(dá)到了集合末尾步清,將拋出NoSuchElementException,所以在調(diào)用next方法前要先調(diào)用hasNext方法檢測(cè)虏肾。

ArrayList<String> strings = new ArrayList<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("d");
strings.add("e");

Iterator<String> iterator = strings.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

當(dāng)然也可以通過(guò)foreach循環(huán)遍歷:

for (String s :
       strings ) {
    System.out.println(s);
}

編譯器會(huì)把for each語(yǔ)法結(jié)構(gòu)轉(zhuǎn)為上面的迭代器的結(jié)構(gòu)廓啊。這種方式可以遍歷所有實(shí)現(xiàn)了Iterable接口的結(jié)構(gòu)。

Iterable

Iterable只包含一個(gè)iterator抽象方法

public interface Iterable<T> {
    
    Iterator<T> iterator();
    ...
}

目的是讓用戶實(shí)現(xiàn)自定義的數(shù)據(jù)結(jié)構(gòu)返回一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象封豪,我們看到ArrayList的實(shí)現(xiàn)如下:

public Iterator<E> iterator() {
    return new Itr();
}

其中Itr是一個(gè)內(nèi)部類(lèi)谴轮,定義在ArrayList中,并實(shí)現(xiàn)了Iterator接口吹埠。

private class Itr implements Iterator<E> {
    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

    public boolean hasNext() {
        return cursor != size;
    }

    @SuppressWarnings("unchecked")
    public E next() {
        checkForComodification();
        int i = cursor;
        if (i >= size)
            throw new NoSuchElementException();
        Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length)
            throw new ConcurrentModificationException();
        cursor = i + 1;
        return (E) elementData[lastRet = i];
    }

    public void remove() {
        if (lastRet < 0)
            throw new IllegalStateException();
        checkForComodification();

        try {
            ArrayList.this.remove(lastRet);
            cursor = lastRet;
            lastRet = -1;
            expectedModCount = modCount;
        } catch (IndexOutOfBoundsException ex) {
            throw new ConcurrentModificationException();
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public void forEachRemaining(Consumer<? super E> consumer) {
        Objects.requireNonNull(consumer);
        final int size = ArrayList.this.size;
        int i = cursor;
        if (i >= size) {
            return;
        }
        final Object[] elementData = ArrayList.this.elementData;
        if (i >= elementData.length) {
            throw new ConcurrentModificationException();
        }
        while (i != size && modCount == expectedModCount) {
            consumer.accept((E) elementData[i++]);
        }
        // update once at end of iteration to reduce heap write traffic
        cursor = i;
        lastRet = i - 1;
        checkForComodification();
    }

    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

最重要的是Java SE8中不寫(xiě)循環(huán)而直接使用forEachRemaining方法就可以使用Lambda表達(dá)式處理每個(gè)元素:

strings.iterator().forEachRemaining(e-> System.out.println(e));

同時(shí)也可是使用Iterable接口中的forEach方法來(lái)遍歷:

strings.forEach(e-> System.out.println(e));
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末第步,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缘琅,更是在濱河造成了極大的恐慌粘都,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刷袍,死亡現(xiàn)場(chǎng)離奇詭異翩隧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)呻纹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)鸽心,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人居暖,你說(shuō)我怎么就攤上這事√僦” “怎么了太闺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嘁圈。 經(jīng)常有香客問(wèn)我省骂,道長(zhǎng)蟀淮,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任钞澳,我火速辦了婚禮怠惶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘轧粟。我一直安慰自己策治,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布兰吟。 她就那樣靜靜地躺著通惫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪混蔼。 梳的紋絲不亂的頭發(fā)上履腋,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音惭嚣,去河邊找鬼遵湖。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晚吞,可吹牛的內(nèi)容都是我干的延旧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼载矿,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼垄潮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起闷盔,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤弯洗,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后逢勾,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體牡整,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年溺拱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了逃贝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡迫摔,死狀恐怖沐扳,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情句占,我是刑警寧澤沪摄,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響杨拐,放射性物質(zhì)發(fā)生泄漏祈餐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一哄陶、第九天 我趴在偏房一處隱蔽的房頂上張望帆阳。 院中可真熱鬧,春花似錦屋吨、人聲如沸蜒谤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)芭逝。三九已至,卻和暖如春渊胸,著一層夾襖步出監(jiān)牢的瞬間旬盯,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工翎猛, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胖翰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓切厘,卻偏偏與公主長(zhǎng)得像萨咳,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疫稿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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

  • 概述 Java集合框架由Java類(lèi)庫(kù)的一系列接口培他、抽象類(lèi)以及具體實(shí)現(xiàn)類(lèi)組成。我們這里所說(shuō)的集合就是把一組對(duì)象組織到...
    absfree閱讀 1,254評(píng)論 0 10
  • title: java集合框架學(xué)習(xí)總結(jié) tags:集合框架 categories:總結(jié) date: 2017-03...
    行徑行閱讀 1,688評(píng)論 0 2
  • 前言:一名iOS開(kāi)發(fā)工程師,正在學(xué)習(xí)Android開(kāi)發(fā),期待各路大神指點(diǎn)和學(xué)習(xí)交流.學(xué)習(xí)交流討論及資料獲取請(qǐng)關(guān)注:...
    極客James閱讀 4,397評(píng)論 0 5
  • 集合框架體系概述 為什么出現(xiàn)集合類(lèi)?方便多個(gè)對(duì)象的操作,就對(duì)對(duì)象進(jìn)行存儲(chǔ),集合就是存儲(chǔ)對(duì)象最常用的一種方法. 數(shù)組...
    acc8226閱讀 771評(píng)論 0 1
  • 第二名 現(xiàn)在小學(xué)語(yǔ)文太難了,看他們的一道作業(yè)題: 要求:把以下四句話用關(guān)聯(lián)詞連接: (1)李姐姐癱瘓了; (2)李...
    享受福袋閱讀 346評(píng)論 0 1