30分鐘學(xué)透設(shè)計(jì)模式3-使用最多的Iterator模式

聲明:原創(chuàng)文章,轉(zhuǎn)載請(qǐng)注明出處撒妈。http://www.reibang.com/p/23e88dfe593b

設(shè)計(jì)模式系列:
30分鐘學(xué)透設(shè)計(jì)模式1-單例模式的前世今生
30分鐘學(xué)透設(shè)計(jì)模式2-隨處可見的Builder模式
30分鐘學(xué)透設(shè)計(jì)模式3-使用最多的Iterator模式
30分鐘學(xué)透設(shè)計(jì)模式4-最簡(jiǎn)單的面向接口編程-簡(jiǎn)單工廠模式
30分鐘學(xué)透設(shè)計(jì)模式5-從代理模式到AOP

一知纷、栗子

先從一個(gè)簡(jiǎn)單的栗子說(shuō)起,有一個(gè)ArrayList需要遍歷屠缭,通常怎么去做呢悟狱?

List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c"));
// 方法 1: foreach
for (String s : list) {
    System.out.println(s);
}
// 方法 2: for循環(huán)
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
// 方法 3: 迭代器
Iterator it = list.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

這里我們不討論這三種方法的效率,但是這幾種肯定我們經(jīng)常使用的磷籍。

1适荣、但是现柠,如下,在我們將List換成了Set之后弛矛,如果盡量不修改代碼的話够吩,這三種遍歷方式有什么變化呢?

Set<String> set = new HashSet<String>(Arrays.asList("a", "b", "c"));

結(jié)論:只有方法1和方法3是可用的丈氓,因?yàn)镾et不是順序結(jié)構(gòu)周循,不能采用for循環(huán)的方式遍歷。

2万俗、進(jìn)一步湾笛,如下,在我們繼續(xù)將Set換成Map之后闰歪,那現(xiàn)在遍歷方法會(huì)怎么樣呢嚎研?

Map<String, String> map = new HashMap<String, String>();

結(jié)論:方法1和3均可用,但是需要稍微修改一點(diǎn)库倘。

// 方法 1
for (Map.Entry<String, String> entry: map.entrySet()) {
        System.out.println(entry.toString());
}
// 方法 3
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}

for each這種方式遍歷的對(duì)象必須是一個(gè)數(shù)組或者是一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象临扮。

無(wú)論存儲(chǔ)結(jié)構(gòu)怎么變,發(fā)現(xiàn)第三種遍歷方式教翩,都沒有什么變化杆勇。這就是我們將要介紹的迭代器(Iterator)模式。

二饱亿、迭代器模式定義

1蚜退、定義

迭代器模式就是提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而不用暴露其內(nèi)部實(shí)現(xiàn)彪笼。在實(shí)際的開發(fā)過(guò)程中钻注,我們可能需要針對(duì)不同的需求,以不同的方式來(lái)遍歷集合對(duì)象杰扫,但不希望在集合對(duì)象的抽象接口層中充斥著各種不同的遍歷操作队寇。

通俗的講膘掰,迭代器為集合(如Collection章姓、List、Set识埋、Map等)提供了統(tǒng)一遍歷接口凡伊,提高代碼復(fù)用性,并隱藏其內(nèi)部實(shí)現(xiàn)窒舟。

2系忙、優(yōu)點(diǎn)

  • 簡(jiǎn)化遍歷方式,不僅可以對(duì)數(shù)組惠豺、有序表進(jìn)行遍歷银还,對(duì)Map等結(jié)構(gòu)亦可风宁。
  • 可提供多種遍歷方法。如對(duì)數(shù)組提供正序蛹疯、逆序的迭代器戒财。
  • 迭代器簡(jiǎn)化了聚合類,而且封裝性強(qiáng)捺弦,用戶只需要得到迭代器就可以遍歷饮寞,而不需要額外關(guān)注遍歷算法。迭代器模式是“單一職責(zé)原則”的完美體現(xiàn)列吼。

3幽崩、缺點(diǎn)

由于迭代器模式將存儲(chǔ)數(shù)據(jù)和遍歷數(shù)據(jù)的職責(zé)分離,增加新的聚合類需要對(duì)應(yīng)增加新的迭代器類寞钥,類的個(gè)數(shù)成對(duì)增加慌申,這在一定程度上增加了系統(tǒng)的復(fù)雜性。

4凑耻、使用場(chǎng)景

  • 訪問一個(gè)聚合對(duì)象的內(nèi)容而無(wú)須暴露它的內(nèi)部表示太示。
  • 需要為聚合對(duì)象提供多種遍歷方式。
  • 為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口香浩。

三类缤、實(shí)現(xiàn)一個(gè)簡(jiǎn)單的迭代器

1、定義Iterator接口

public interface Iterator {
    Object next();
    boolean hasNext();
}

2邻吭、定義集合Container接口(類似List)

public interface Container {
    void add(Object obj);
    Iterator createIterator();
}

3餐弱、定義具體的集合類ConcreteContainer(類似ArrayList)

public class ConcreteContainer implements Container {
    private List<Object> list;

    public ConcreteContainer(List<Object> list) {
        this.list = list;
    }

    public void add(Object obj) {
        list.add(obj);
    }

    public Iterator createIterator() {
        return new ConcreteIterator();
    }

    private class ConcreteIterator implements Iterator {
        private int cursor;

        public Object next() {
            if (hasNext()) {
                return list.get(cursor++);
            }
            return null;
        }

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

4、測(cè)試類

經(jīng)過(guò)上面三個(gè)步驟囱晴,我們已經(jīng)完成了一個(gè)簡(jiǎn)單版的迭代器膏蚓。下面我們測(cè)試下及遍歷功能。

public static void main(String[] args) {
    Container container = new ConcreteContainer(new ArrayList<Object>());
    container.add("a");
    container.add("b");
    container.add("c");

    Iterator iterator = container.createIterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next());
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末畸写,一起剝皮案震驚了整個(gè)濱河市驮瞧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌枯芬,老刑警劉巖论笔,帶你破解...
    沈念sama閱讀 206,126評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異千所,居然都是意外死亡狂魔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門淫痰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)最楷,“玉大人,你說(shuō)我怎么就攤上這事∽阉铮” “怎么了烈评?”我有些...
    開封第一講書人閱讀 152,445評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)犯建。 經(jīng)常有香客問我础倍,道長(zhǎng),這世上最難降的妖魔是什么胎挎? 我笑而不...
    開封第一講書人閱讀 55,185評(píng)論 1 278
  • 正文 為了忘掉前任沟启,我火速辦了婚禮,結(jié)果婚禮上犹菇,老公的妹妹穿的比我還像新娘德迹。我一直安慰自己,他們只是感情好揭芍,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,178評(píng)論 5 371
  • 文/花漫 我一把揭開白布胳搞。 她就那樣靜靜地躺著,像睡著了一般称杨。 火紅的嫁衣襯著肌膚如雪肌毅。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 48,970評(píng)論 1 284
  • 那天姑原,我揣著相機(jī)與錄音悬而,去河邊找鬼。 笑死锭汛,一個(gè)胖子當(dāng)著我的面吹牛笨奠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播唤殴,決...
    沈念sama閱讀 38,276評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼般婆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了朵逝?” 一聲冷哼從身側(cè)響起蔚袍,我...
    開封第一講書人閱讀 36,927評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎配名,沒想到半個(gè)月后啤咽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡段誊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,883評(píng)論 2 323
  • 正文 我和宋清朗相戀三年闰蚕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栈拖。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片连舍。...
    茶點(diǎn)故事閱讀 37,997評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出索赏,到底是詐尸還是另有隱情盼玄,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評(píng)論 4 322
  • 正文 年R本政府宣布潜腻,位于F島的核電站埃儿,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏融涣。R本人自食惡果不足惜童番,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,213評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望威鹿。 院中可真熱鬧剃斧,春花似錦、人聲如沸忽你。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)科雳。三九已至根蟹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間糟秘,已是汗流浹背简逮。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評(píng)論 1 260
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留尿赚,地道東北人买决。 一個(gè)月前我還...
    沈念sama閱讀 45,423評(píng)論 2 352
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吼畏,于是被迫代替她去往敵國(guó)和親督赤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,722評(píng)論 2 345