設(shè)計(jì)模式-迭代器模式

迭代器模式是數(shù)據(jù)訪問遍歷的一種行為模式泽疆。java中List户矢、Set、Map 等都包含了迭代器殉疼。迭代器提供一個(gè)對(duì)象來順序訪問聚合對(duì)象中的一系列數(shù)據(jù)梯浪,而不暴露聚合對(duì)象的內(nèi)部表示捌年。迭代器模式的優(yōu)點(diǎn):

  • 無須暴露聚合對(duì)象的內(nèi)部表示
  • 遍歷任務(wù)交由迭代器完成,簡化聚合類
  • 遍歷的方式可擴(kuò)展

模式結(jié)構(gòu)

迭代器模式主要包含以下角色挂洛。

  1. 抽象聚合(Aggregate)角色:定義存儲(chǔ)礼预、添加、刪除聚合對(duì)象以及創(chuàng)建迭代器對(duì)象的接口虏劲。
  2. 具體聚合(ConcreteAggregate)角色:實(shí)現(xiàn)抽象聚合類托酸,返回一個(gè)具體迭代器的實(shí)例。
  3. 抽象迭代器(Iterator)角色:定義訪問和遍歷聚合元素的接口柒巫,通常包含 hasNext()励堡、first()、next() 等方法吻育。
  4. 具體迭代器(Concretelterator)角色:實(shí)現(xiàn)抽象迭代器接口中所定義的方法念秧,完成對(duì)聚合對(duì)象的遍歷,記錄遍歷的當(dāng)前位置布疼。

源碼導(dǎo)讀

集合類的迭代器我們沒少用,我們來看看它的相關(guān)源碼吧币狠,以 ArrayList 為例游两,它就是一個(gè)collection的具體聚合,其方法 iterator() 便是獲取迭代器的方法:

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

z這個(gè) Itr 是它的內(nèi)部類:

 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];
        }
    
    // 部分源碼省略
    }    

它的私有內(nèi)部類實(shí)現(xiàn)了 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());
    }
}

這就是一個(gè)迭代器的抽象接口漩绵。定義了對(duì)聚合對(duì)象的訪問方法贱案。

這里說一下設(shè)計(jì)亮點(diǎn) Itr ,它是個(gè)私有的內(nèi)部類止吐;這樣做的好處是做到了足夠的約束宝踪,避免使用者去以不合理的方式創(chuàng)建迭代器,并且可以自由的訪問外部類的私有屬性碍扔, 這樣的設(shè)計(jì)方式同樣適合建造者模式瘩燥。

我們簡單分析下 Itr 對(duì)外部類屬性的遍歷 它的三個(gè)屬性值標(biāo)記遍歷的相關(guān)信息。

    int cursor;       // index of next element to return
    int lastRet = -1; // index of last element returned; -1 if no such
    int expectedModCount = modCount;

我們看 Itr.next() 方法不同,Object[] elementData = ArrayList.this.elementData 就是獲取外部類對(duì)象的數(shù)據(jù)厉膀,這個(gè)elementData 就是實(shí)際存儲(chǔ)我們數(shù)據(jù)的對(duì)象,所以說ArrayList的底層是數(shù)組二拐;這里有個(gè)有意思的冷知識(shí) transient 關(guān)機(jī)鍵服鹅,在 ArrayList 中 它屬性是這樣定義的:

transient Object[] elementData

這個(gè)關(guān)鍵字修飾的屬性,在序列化對(duì)象的時(shí)候百新,這個(gè)屬性不會(huì)被序列化企软,這么做的原因感興趣的可以自行百度,這里不做太多分析饭望。

點(diǎn)擊關(guān)注我的博客

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仗哨,一起剝皮案震驚了整個(gè)濱河市聚蝶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌藻治,老刑警劉巖碘勉,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異桩卵,居然都是意外死亡验靡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門雏节,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胜嗓,“玉大人,你說我怎么就攤上這事钩乍〈侵荩” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵寥粹,是天一觀的道長变过。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任溪胶,我火速辦了婚禮,結(jié)果婚禮上崭孤,老公的妹妹穿的比我還像新娘。我一直安慰自己糊肠,他們只是感情好辨宠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著货裹,像睡著了一般嗤形。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泪酱,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天派殷,我揣著相機(jī)與錄音,去河邊找鬼墓阀。 笑死毡惜,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的斯撮。 我是一名探鬼主播经伙,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了帕膜?” 一聲冷哼從身側(cè)響起枣氧,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎垮刹,沒想到半個(gè)月后达吞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荒典,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年酪劫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寺董。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡覆糟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出遮咖,到底是詐尸還是另有隱情滩字,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布御吞,位于F島的核電站麦箍,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏魄藕。R本人自食惡果不足惜内列,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望背率。 院中可真熱鬧,春花似錦嫩与、人聲如沸寝姿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饵筑。三九已至,卻和暖如春处坪,著一層夾襖步出監(jiān)牢的瞬間根资,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工同窘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留玄帕,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓想邦,卻偏偏與公主長得像裤纹,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子丧没,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

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

  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是迭代器模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 優(yōu)點(diǎn)和缺點(diǎn) 適用環(huán)境 模式應(yīng)用 一...
    w1992wishes閱讀 517評(píng)論 0 1
  • 在閻宏博士的《JAVA與模式》一書中開頭是這樣描述迭代子(Iterator)模式的:迭代子模式又叫游標(biāo)(Curso...
    Ant_way閱讀 415評(píng)論 0 0
  • 迭代器模式(Iterator) 在現(xiàn)實(shí)生活以及程序設(shè)計(jì)中鹰椒,經(jīng)常要訪問一個(gè)聚合對(duì)象中的各個(gè)元素锡移,如“數(shù)據(jù)結(jié)構(gòu)”中的鏈...
    Acton_zhang閱讀 227評(píng)論 1 1
  • 1.迭代器模式介紹 迭代器模式:提供一種方法順序的訪問一個(gè)聚合對(duì)象中各個(gè)元素,而又不暴露該對(duì)象的內(nèi)部表示漆际。 2.迭...
    smallmartial閱讀 233評(píng)論 0 1
  • 對(duì)有些人而言淆珊,一個(gè)人,就是一座城奸汇。 這座城市施符,像一個(gè)巨大的站臺(tái),有人剛剛到達(dá)茫蛹,亦有人剛剛離去操刀。 屈指一算,在這座城...
    溫瞳_ebb2閱讀 234評(píng)論 0 1