Iterator源碼逐條解析

一家之言 姑妄言之 絮絮叨叨 不足為訓

Iterator接口注釋翻譯:

?? 集合上的迭代器。迭代器在Java集合框架中代替了枚舉。迭代器與枚舉有兩個不同之處:
?? 1.迭代器允許調用者使用定義良好的語義在迭代期間從基礎集合中刪除元素。
?? 2.方法名已經得到了改進。
?? 該接口是Java集合框架的成員。


筆者廢話:

?? 這里的Iterator譯為迭代器,那么對于我來說,其實這就是個循環(huán)對象而已。它作為一個接口,也就是一個對象,其工作就是遍歷集合中的對象,當然,這些集合對象需要去實現(xiàn)它。你可以理解它為for循環(huán)的變種,但是這里也僅僅表明“理解”而不是等同。
?? 也只有實現(xiàn)了Iterator接口的對象才能調用其方法,這點是毋庸置疑的。所以,我們也可以理解為Iterator就是那些實現(xiàn)了它的集合本身所擁有的屬性,而這個屬性也規(guī)定了,我們的集合,是可以遍歷的。


Iterator接口信息:

public interface Iterator<E>

?? 我們可以清楚的看到,Iterator是一個接口,而且這里還規(guī)定了泛型機制。而通過接口注釋來看,這個泛型E就是這個迭代器返回的元素的類型。


Iterator接口方法信息:

/**
 * 如果該迭代器內有更多的元素,則返回true。換句話說,如果next將返回
 * 一個元素而不是拋出一個異常,則返回true
 * @return 如果該迭代器內有更多的元素,則為真
 */
boolean hasNext();

?? 這個方法意在詢問當前遍歷的容器中是否含有下一個元素。這里會涉及到一個指針操作,當然,我們java宣稱的可是沒有指針,所以,這我們可以把它稱之為“指向”。一般來說,如果我們使用了某個集合的Iterator對象后,會在這個集合的上方出現(xiàn)一個空值,而我們的Iterator對象就指向這個空值。
?? 但是需要注意的是,這個方法僅僅是詢問下一個元素是否存在,此時并不移動指向位置,只有調用了next()方法后,這個指向位置才會進行移動,即,移動到下一項。

/**
 * 返回迭代器中的下一個元素。
 * @return 返回迭代器中的下一個元素。
 * @throws 如果迭代沒有更多的元素則拋出NoSuchElementException異常
 */
E next();

?? 這個方法是與hasNext()方法遙相呼應的。它代表著返回迭代器中的下一個元素。一般來說,我們都會通過hasNext()方法來判斷是否有下一個元素,一旦有,那么就調用next()方法展示(取出)這個元素。
?? 重復上面的一段話:調用了next()方法后,容器的指向位置會進行移動,即,移動到下一項。

/**
 * 從基礎集合中移除此迭代器返回的最后一個元素(可選操作)。此方法在每次
 * 調用next時只能調用一次。如果在迭代過程中以調用此方法以外的任何方式
 * 修改了底層集合,則迭代器的行為是未指定的。
 * 
 * @implSpec
 * 默認實現(xiàn)拋出UnsupportedOperationException異常,不執(zhí)行其他操作。
 * 
 * @throws 如果這個迭代器不支持刪除操作則拋出
 * UnsupportedOperationException異常
 * @throws 如果尚未next()方法,或者在最后一次調用next()方法之后已經
 * 調用了remove方法則拋出IllegalStateException異常
 */
default void remove() {
    throw new UnsupportedOperationException("remove");
}

?? 這個移除方法其實挺有的說的。
?? 首先,我們看它的修飾符,是default。這個default區(qū)別于我們類里面成員屬性的default。這個是JAVA 1.8給接口新添加的特性。它表示我們可以在接口里面進行方法的默認實現(xiàn)。當然,這個方法也可被其實現(xiàn)類進行重寫
?? 其次,這個方法刪除的是上一次調用了next()方法時返回的元素。所以,這個方法必須在調用next()方法之后才可調用,如果在next()方法之前調用將會拋出IllegalStateException異常。這塊不是絕對啊,這塊不是絕對啊,你試試ArrayList就行了。試一下只添加一個元素就開始遍歷,試試啊小可愛~
?? 再次,我們從其代碼入手,會發(fā)現(xiàn)它默認拋出UnsupportedOperationException異常。其本質是告訴我們,不是所有的實現(xiàn)類都支持Iteratorremove()移除操作。所以,這個方法肯定是會由其部分實現(xiàn)類進行重新覆寫,而不是僅僅提供一個無用的方法。
?? 這里就不再舉例了,因為本身這就是一個接口,其各自的實現(xiàn)類都幾乎重寫了這個方法,所以這里即使舉例也是利用其實現(xiàn)類。并且,各自的實現(xiàn)還略有差別。因此,大家可以移步我其他的集合源碼分析篇章來具體查看這些示例。

/**
 * 為每個剩余元素執(zhí)行給定的操作,直到處理完所有元素或操作引發(fā)異常。
 * 如果指定了迭代的順序,則按照迭代的順序執(zhí)行操作。操作引發(fā)的異常將
 * 被轉發(fā)給調用者。
 * 
 * @implSpec
 * 默認實現(xiàn)的行為就像:
 *  while (hasNext())
         action.accept(next());
         
 * @param action The action to be performed for each element
 * @throws NullPointerException if the specified action is null
 * @since 1.8
 */
default void forEachRemaining(Consumer<? super E> action) {
    Objects.requireNonNull(action);
    while (hasNext())
        action.accept(next());
}

?? 這里是Iterator接口中最后一個方法,它也是JAVA1.8新定義的一個方法。需要注意的是它也是一個被default修飾符修飾的方法,即,它也是這個接口多定義具有默認實現(xiàn)的方法。
?? 從方法名來看,它就是一個遍歷方法,只不過它遍歷的是剩余元素。那么從注釋上面來看,也表明了該方法為每個剩余元素執(zhí)行給定的操作,直到處理完所有元素或操作引發(fā)異常。
?? 不過這里筆者需要表明的是,這里所謂的“剩余”其實無所謂。我們從其代碼來看,它就是在遍歷元素,然后對遍歷出的元素做出某種操作。當然,這種操作我們還是需要具體到實現(xiàn)類的。
?? 當然,根據我們文章的總意,還是需要講解一下其代碼的內部實現(xiàn)。
?? 首先我們可以看到其傳進來的參數是一個Consumer<? super E>類,它是一個函數式編程接口。這個行為也表明了我們需要處理的元素必須是當前Iterator泛型內指定類型的子類,或其本類。
?? 接下來的代碼會對其進行一次非空判斷,只有通過判斷才可以進行下一步操作。
?? 當我們的參數通過了非空判斷之后,剩下的,就開始了while循環(huán)進行遍歷。然后對其遍歷的元素進行處理。當然,這種處理之前也說過了,是需要具體到實現(xiàn)類的。到底做了什么處理,不能從這里得知,而應該去看其具體的實現(xiàn)方法。
?? 這些具體的實現(xiàn)方法我會在其具體的實現(xiàn)類里面具體做介紹,這里還是不摻雜那么多的解釋或舉例。僅僅留給這個Iterator接口一個說一是一的解析吧。
?? 至此,我們Iterator到此全部解析完畢(?_?)。

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

友情鏈接更多精彩內容