聊一聊Iterable與Iterator的那些事!

Coder程式設計發表於2019-03-25

前言

歡迎關注公眾號:Coder程式設計 獲取最新原創技術文章和相關免費學習資料,隨時隨地學習技術知識!

在上一篇文章通過面試題,讓我們來了解Collection,我們會發現Collection介面之上還有一個介面Iterable, Iterable介面裡面又有Iterator介面,那他們到底有什麼區別呢?我們接下來就來了解下Iterable與Iterator相關內容,也就是本章的主要內容了,說不定 在我們面試過程中,也會遇到一些問題呢。那我們就開始吧~

涉及面試題:

  • 1.說一說Iterable?
  • 2.Iterable結構?
  • 3.說一說Iterator?
  • 4.Iterator結構?
  • 5.forEachRemaining()與forEach()方法的區別?
  • 6.Iterator如何使用?
  • 7.Iterable與Iterator之間的區別與聯絡?

上面的面試題可以看出,其實都是一回事,只是換了一種提問方式,只要我們能掌握核心要點,隨便面試官怎麼提問,我們都能輕鬆應對!

來源百度百科:

Iterable: 百度的時候,我卻只看到了百度翻譯:可迭代的; 可重複的; 迭代的; 因此我們可以知道,實現了這個介面的集合物件支援迭代,是可迭代的。

Iterator: Iterator我們一般叫迭代器,它就是提供迭代機制的物件,具體如何迭代,都是Iterator介面規範的。通過UML圖,我們也可以看出Iterable介面是Java集合框架的頂級介面, 實現此介面使集合物件可以通過迭代器遍歷自身元素。同時在Java設計模式中也有一種模式——迭代器模式.(在後續的文章我們會介紹相關設計模式,敬請關注~) 可以看出Iterator是迭代器模式最好的一個應用例子!

聊一聊Iterable與Iterator的那些事!

1.說一說Iterable?

聊一聊Iterable與Iterator的那些事!

由原始碼圖可以看出,Iterable有三個方法,分別是

  • Iterator iterator();
  • default void forEach(Consumer<? super T> action){}; JDK 1.8後新增
  • default Spliterator spliterator(){}; JDK 1.8後新增

接下來我們簡單介紹下這裡面的方法。

1.1 Iterable介面中的iterator() 方法

Iterator<T> iterator();

複製程式碼

該介面主要是返回T型別的元素上的一個迭代器。下面再詳細介紹Iterator。

1.2 Iterable介面中的forEach() 方法

default void forEach(Consumer<? super T> action) {
    	// 驗證action是否為null,如果action為null,則丟擲NullPointerException
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
複製程式碼

該方法是迴圈輸出,對內部元素進行遍歷,並對元素進行指定的操作。例如:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
 numbers.forEach(integer -> System.out.println(integer));
複製程式碼

對原始碼註釋翻譯: 對這個Iterable的每一個元素執行給定的動作指導所有元素都被處理或者動作丟擲一個異常 為止。除非被實現類指定,動作將以迭代的順序執行(如果一個迭代的順序被指定。)被動作 丟擲的異常將被傳遞給呼叫者

1.3 Iterable介面中的spliterator() 方法

default Spliterator<T> spliterator() {
    return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
複製程式碼

該方法提供了一個可以並行遍歷元素的迭代器,以適應現在cpu多核時代並行遍歷的需求。簡單說:分割,增加並行處理能力 對原始碼註釋翻譯: 建立一個被這個Iterable介面描述的元素上Spliterator。預設實現從iterable的Iterator中建立一個早期繫結的spliterator。這個spliterator 繼承iterable的iterator的fail-fast性質。 預設實現應該總是被重寫。被預設實現返回的spliterator擁有不好分解能力,是不依據指定 大小定製的,而且不報告任何spliterator的性質。實現類差不多總是能提供更好的實現。

2.說一說Iterator?

2.1 Iterator是什麼?

Iterator被稱之為順序遍歷迭代器,jdk中預設對集合框架中資料結構做了實現。 Iterator在實際應用中有一個比較好的點就是,可以一邊遍歷一遍刪除元素。後面我會通過ArrayList中的Iterator()方法進行說明。

2.2 Iterator結構?

聊一聊Iterable與Iterator的那些事!

由原始碼圖Iterator介面中定義了四個方法,分別是

  • boolean hasNext():如果被迭代遍歷的集合還沒有被遍歷完,返回True
  • Object next():返回集合裡面的下一個元素
  • remove():刪除集合裡面上一次next()方法返回的元素
  • void forEachRemaining(Consumer action):JDK 1.8後新增預設方法 使用Lambda表示式來遍歷集合元素

2.3 Iterator介面中的forEachRemaining() 方法

在JDK1.8之後Iterator中增加的一個預設方法

//使用方法
List<String> arr=new ArrayList<>();
arr.add("hello");
arr.add(("world"));
arr.iterator().forEachRemaining(str-> System.out.println(str));
複製程式碼

2.3.1 forEachRemaining()與forEach()方法之間的區別?

forEachRemaining()原始碼:

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

forEach()原始碼:

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}
複製程式碼

通過原始碼,我們可以看出他們之間的區別與聯絡。 相同點:

  • 都可以遍歷集合
  • 都是介面的預設方法
  • 都是1.8版本引入的

區別:

  • forEachRemaining()方法內部是通過使用迭代器Iterator的所有元素,forEach()方法內部使用的是增強for迴圈。
  • forEach()方法可以多次呼叫,forEachRemaining()方法第二次呼叫不會做任何操作,因為不會有下一個元素。

3.Iterator如何使用?

簡單舉個小栗子

List list = new ArrayList();
list.add("公眾號");
list.add("Coder程式設計");
for (Iterator iter = list.iterator(); iter.hasNext();) {
String str = (String)iter.next();
System.out.println(str);
}
/*迭代器用於while迴圈
Iterator iter = list.iterator();
while(iter.hasNext()){
String str = (String) iter.next();
System.out.println(str);
}
*/
複製程式碼

推薦閱讀

文末

本章節主要介紹了Iterable與Iterator之間的區別與聯絡,以及其他方面的小知識點,也是面試過程中會出現的內容點。 歡迎關注公眾號:Coder程式設計 獲取最新原創技術文章和相關免費學習資料,隨時隨地學習技術知識!

歡迎大家關注並Star~

聊一聊Iterable與Iterator的那些事!

相關文章