關(guān)于 Java Iterator(迭代器)學(xué)習(xí)筆記

相信 “迭代” 對(duì)于Java程序員來(lái)說(shuō)并不陌生(當(dāng)然砾莱,其他語(yǔ)言的程序員也是如此)债鸡,在處理數(shù)據(jù)時(shí)箩兽,不可避免地會(huì)存在對(duì)數(shù)據(jù)的大量遍歷操作沃疮。對(duì)于我自己而言薇溃,學(xué)習(xí)使用Java語(yǔ)言?xún)赡陼r(shí)間雀费,對(duì)于“迭代”的概念還停留在 for:each,for:i的遍歷階段。今天用到了JDK 提供的迭代接口進(jìn)行 Java 集合的迭代痊焊,便決定作以筆記盏袄,留作以后學(xué)習(xí)。

普通 Java 集合迭代(遍歷)

迭代可以簡(jiǎn)單理解為遍歷薄啥,在沒(méi)有 JDK 并未提供迭代器時(shí)辕羽,我們對(duì)于數(shù)據(jù)的遍歷處理如下:

  • 對(duì)于數(shù)組的遍歷處理:
Bean[] beans = new Bean[5];

for (int i = 0; i < beans.length; i++) {
    beans[i] = new Bean();
    // todo something
}
  • 對(duì) ArrayList 的遍歷處理:
ArrayList<Bean> beanArrayList = new ArrayList<Bean>();
for (int i = 0; i < beanArrayList.size(); i++) {
    beanArrayList.add(new Bean());
    // todo something
}

可以看出,如果我們想對(duì)一個(gè)空的 Java 集合添加數(shù)據(jù)垄惧,那我們就必須知道該集合內(nèi)部的數(shù)據(jù)結(jié)構(gòu)(即刁愿,以數(shù)組和 ArrayList 為例,添加時(shí)的操作應(yīng)該是beans[i] = new Bean();還是beanArrayList.add(new Bean());)到逊,這樣就導(dǎo)致了訪(fǎng)問(wèn)邏輯與集合的結(jié)構(gòu)本身緊密耦合(即铣口,每一種不同的數(shù)據(jù)集合對(duì)應(yīng)了不同的便利方法),這會(huì)使得代碼無(wú)法復(fù)用觉壶。

Iterator 可以輕松的解決上述問(wèn)題.

java.util.Iterator

看一下官方未出的解釋?zhuān)?/p>

public interface Iterator<E>
An iterator over a collection. Iteratortakes the place of Enumeration
in the Java Collections Framework. Iterators differ from enumerations in two ways:

  • Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
  • Method names have been improved.
    This interface is a member of the Java Collections Framework

就是說(shuō)脑题,Iterator是一個(gè)對(duì) collection 集合進(jìn)行迭代的迭代器(接口)。Iterator迭代器取代了 Java Collections Framework 中的 Enumeration铜靶。該接口是 Java Collections Framework 的成員叔遂。迭代器與枚舉有兩點(diǎn)不同:

  • 迭代器允許調(diào)用者利用定義良好的語(yǔ)義在迭代期間從迭代器所指向的 collection 移除元素。
  • 方法名稱(chēng)得到了改進(jìn)争剿。
    .

這也就意味著已艰,Iterator 使用相同的訪(fǎng)問(wèn)邏輯完成集合的遍歷,使得我們?cè)谠L(fǎng)問(wèn)集合元素時(shí),無(wú)需關(guān)心不同的集合內(nèi)部結(jié)構(gòu)蚕苇。從而降低訪(fǎng)問(wèn)邏輯與集合本身的耦合度哩掺。

Iterator接口源代碼如下:

package java.util;

import java.util.function.Consumer;

public interface Iterator<E> {
    // 返回迭代是否有更多的元素。
    boolean hasNext();

    // 返回迭代器剛越過(guò)的元素的引用
    E next();

    // 從底層集合中移除此迭代器返回的最后一個(gè)元素(可選操作)
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

    // 對(duì)每個(gè)剩余的元素執(zhí)行給定的操作涩笤,直到處理完所有元素或操作拋出異常
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

如何使用 Iterator

在使用中嚼吞,我們既可以借助hasNext()next()方法盒件,對(duì)已知集合結(jié)構(gòu)的集合對(duì)象完成簡(jiǎn)單的迭代(類(lèi)似于之前的方案),就像這樣:

Iterator<Bean> beanIterator = beanArrayList.iterator();
while (beanIterator.hasNext()) {
    Bean bean = beanIterator.next();
    // todo something
}



更新于2017.12.03

僅僅這樣不是與之前的方案沒(méi)什么區(qū)別了嗎誊薄?當(dāng)然履恩,它能做的還可以更多。做到真正不去關(guān)心集合內(nèi)部結(jié)構(gòu)的迭代手段呢蔫,下述代碼是對(duì)一個(gè)集合對(duì)象的迭代:

public static boolean isExist(Collection<Bean> beans, Bean bean) {
    Iterator<Bean> iterator = beans.iterator();
    System.out.println(beans.getClass().getSimpleName() + ":");
    while (iterator.hasNext()) {
        if (iterator.next().equals(bean)) {
            System.out.println("集合中已存在 Bean[" + bean + "]");
            return true;
        }
    }

    return false;
}

Test:

public static final void main(String[] args) {
    Bean bean0 = new Bean().setId("01");
    Bean bean1 = new Bean().setId("02");
    
    ArrayList<Bean> beanArrayList = new ArrayList<>();
    Queue<Bean> beanQueue = new LinkedBlockingQueue<>();
    HashMap<Bean, Bean> map = new HashMap<>();

    beanArrayList.add(bean0);
    beanArrayList.add(bean1);

    map.put(bean0, bean0);
    map.put(bean1, bean1);

    beanQueue.add(bean0);
    beanQueue.add(bean1);

    isExist(map.keySet(), bean0);
    isExist(beanArrayList, bean1);
    isExist(beanQueue, bean1);
}

輸出結(jié)果:

KeySet:
    集合中已存在 Bean[Bean{id='01', password='null'}]
ArrayList:
    集合中已存在 Bean[Bean{id='02', password='null'}]
LinkedBlockingQueue:
    集合中已存在 Bean[Bean{id='02', password='null'}]

總結(jié)

所有Collection框架中的j幾乎所有的集合類(lèi)(或接口)(如ArrayList切心、Set、Queue等)都實(shí)現(xiàn)了(接口也聲明了iterator()方法)自己的內(nèi)部的迭代器片吊,但無(wú)疑都是Iterator的實(shí)現(xiàn)绽昏。

不過(guò)據(jù)我現(xiàn)在所了解到的,數(shù)組由于其本身的實(shí)現(xiàn)方案與 "編譯處理和
JVM 的native()方法有關(guān)俏脊,似乎不能直接獲取到其本身的迭代器全谤。如果有哪位朋友知道相關(guān)方法,請(qǐng)?jiān)u論告知爷贫,不勝感謝认然。





這是第一次嘗試寫(xiě)學(xué)習(xí)筆記,希望以后可以堅(jiān)持下去漫萄,事無(wú)巨細(xì)地卷员,從點(diǎn)滴累積自己的財(cái)富。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腾务,一起剝皮案震驚了整個(gè)濱河市毕骡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岩瘦,老刑警劉巖未巫,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異启昧,居然都是意外死亡叙凡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)箫津,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)狭姨,“玉大人,你說(shuō)我怎么就攤上這事苏遥。” “怎么了赡模?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵田炭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我漓柑,道長(zhǎng)教硫,這世上最難降的妖魔是什么叨吮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮瞬矩,結(jié)果婚禮上茶鉴,老公的妹妹穿的比我還像新娘。我一直安慰自己景用,他們只是感情好涵叮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著伞插,像睡著了一般割粮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上媚污,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天舀瓢,我揣著相機(jī)與錄音,去河邊找鬼耗美。 笑死京髓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的商架。 我是一名探鬼主播堰怨,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼甸私!你這毒婦竟也來(lái)了诚些?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤皇型,失蹤者是張志新(化名)和其女友劉穎诬烹,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體弃鸦,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡绞吁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唬格。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片家破。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖购岗,靈堂內(nèi)的尸體忽然破棺而出汰聋,到底是詐尸還是另有隱情,我是刑警寧澤喊积,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布烹困,位于F島的核電站,受9級(jí)特大地震影響乾吻,放射性物質(zhì)發(fā)生泄漏髓梅。R本人自食惡果不足惜拟蜻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望枯饿。 院中可真熱鬧酝锅,春花似錦、人聲如沸奢方。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)袱巨。三九已至阁谆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愉老,已是汗流浹背场绿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫉入,地道東北人焰盗。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像咒林,于是被迫代替她去往敵國(guó)和親熬拒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

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

  • 1 場(chǎng)景問(wèn)題# 1.1 工資表數(shù)據(jù)的整合## 考慮這樣一個(gè)實(shí)際應(yīng)用:整合工資表數(shù)據(jù)垫竞。 這個(gè)項(xiàng)目的背景是這樣的澎粟,項(xiàng)目...
    七寸知架構(gòu)閱讀 2,524評(píng)論 0 53
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)欢瞪,斷路器活烙,智...
    卡卡羅2017閱讀 134,599評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類(lèi)相關(guān)的語(yǔ)法遣鼓,內(nèi)部類(lèi)的語(yǔ)法啸盏,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法骑祟,線(xiàn)程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,582評(píng)論 18 399
  • 30歲了回懦,終于從一個(gè)程序員變成了另一個(gè)員
    笨笨羊在簡(jiǎn)書(shū)閱讀 257評(píng)論 0 0
  • 第一次正式開(kāi)發(fā)一個(gè)小程序,就從以下幾個(gè)方面來(lái)談一談小程序的開(kāi)發(fā)過(guò)程和心得吧次企,主要說(shuō)說(shuō)這次項(xiàng)目中用到的功能怯晕。 數(shù)據(jù)請(qǐng)...
    Modigliani閱讀 2,405評(píng)論 0 6