Java集合源碼分析之Iterable概述

前言

當我們想要遍歷集合時,Java為我們提供了多種選擇,通常有以下三種寫法:

  • 寫法1:for循環(huán)
for (int i = 0, len = strings.size(); i < len; i++) {
    System.out.println(strings.get(i));
}
  • 寫法2:foreach循環(huán)
for (String var : strings) {
    System.out.println(var);
}
  • 寫法3:Iterator
Iterator iterator = strings.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

那么以上三種遍歷方式有何區(qū)別呢?for循環(huán)我們很熟悉了,就是根據(jù)下標來獲取元素,這個特性與數(shù)組十分吻合,不熟悉的朋友可以閱讀前面講解數(shù)組的文章。foreach則主要對類似鏈表的結(jié)構(gòu)提供遍歷支持,鏈表沒有下標,所以使用for循環(huán)遍歷會大大降低性能。Iterator就是我們今天要講述的主角,它實際上就是foreach。

那么,為什么集合可以進行foreach遍歷,而我們自己定義的Java對象卻不可以呢?有沒有辦法讓任何對象都支持這種遍歷方式?下面的內(nèi)容會告訴我們答案。

Iterable

Iterable是迭代器的意思,作用是為集合類提供for-each循環(huán)的支持。由于使用for循環(huán)需要通過位置獲取元素,而這種獲取方式僅有數(shù)組支持,其他許多數(shù)據(jù)結(jié)構(gòu),比如鏈表,只能通過查詢獲取數(shù)據(jù),這會大大的降低效率。Iterable就可以讓不同的集合類自己提供遍歷的最佳方式。

Iterable的文檔聲明僅有一句:

Implementing this interface allows an object to be the target of the "for-each loop" statement.

它的作用就是為Java對象提供foreach循環(huán),其主要方法是返回一個Iterator對象:

Iterator<T> iterator();

也就是說,如果想讓一個Java對象支持foreach,只要實現(xiàn)Iterable接口,然后就可以像集合那樣,通過Iterator iterator = strings.iterator()方式,或者使用foreach,進行遍歷了。

Iterator

Iterator是foreach遍歷的主體,它的代碼實現(xiàn)如下:

// 判斷一個對象集合是否還有下一個元素
boolean hasNext();

// 獲取下一個元素
E next();

// 刪除最后一個元素。默認是不支持的,因為在很多情況下其結(jié)果不可預(yù)測,比如數(shù)據(jù)集合在此時被修改
default void remove(){...}

// 主要將每個元素作為參數(shù)發(fā)給action來執(zhí)行特定操作
default void forEachRemaining(Consumer<? super E> action){...}

Iterator還有一個子接口,是為需要雙向遍歷數(shù)據(jù)時準備的,在后續(xù)分析ArrayListLinkedList時都會看到它。它主要增加了以下幾個方法:

// 是否有前一個元素
boolean hasPrevious();

// 獲取前一個元素
E previous();

// 獲取下一個元素的位置
int nextIndex();

// 獲取前一個元素的位置
int previousIndex();

// 添加一個元素
void add(E e);

// 替換當前元素值
void set(E e);

總結(jié)

在Java中有許多特性都是通過接口來實現(xiàn)的,foreach循環(huán)也是。foreach主要是解決for循環(huán)依賴下標的問題,為高效遍歷更多的數(shù)據(jù)結(jié)構(gòu)提供了支持。如果你清楚數(shù)組和鏈表的區(qū)別,應(yīng)該就可以回答以下問題了:

for與foreach有何區(qū)別,哪個更高效?

上一篇:Java集合源碼分析之基礎(chǔ)(六):紅黑樹(RB Tree)

下一篇:Java集合源碼分析之超級接口:Collection


我是飛機醬,如果您喜歡我的文章,可以關(guān)注我~

編程之路,道阻且長。唯,路漫漫其修遠兮,吾將上下而求索。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java集合框架 Java中封裝了許多常用的數(shù)據(jù)結(jié)構(gòu),稱為集合框架,可以有效組織數(shù)據(jù),提高程序性能。最初Java只...
    Steven1997閱讀 1,113評論 0 2
  • 一.線性表 定義:零個或者多個元素的有限序列。也就是說它得滿足以下幾個條件:??①該序列的數(shù)據(jù)元素是有限的。??②...
    Geeks_Liu閱讀 2,772評論 1 12
  • Collection接口 Collection接口是所有集合的祖先類。他有兩個構(gòu)造方法,一個無參構(gòu)造,一個是帶Co...
    夜幕繁華閱讀 690評論 0 0
  • 黑黑的夜 猶如母親溫暖的懷抱 每當走進這個時刻, 便覺得是那么的安全可依靠 于是所有的情愫便一起涌上心頭 在這里淋...
    文卷閱讀 519評論 2 16

友情鏈接更多精彩內(nèi)容