天天看點

Java疊代器Iterator

之前我們實作了疊代器模式,很多程式設計語言實際上已經内置了疊代器類,比如Java就為我們實作了疊代器Iterator。我們首先來看Iterator中的源碼。

通過JDK源碼我們發現Iterator是一個接口,包含三個方法:hasNext、next、remove。

Iterator是一個接口,那如何來建立一個執行個體呢?要記住,疊代器和集合類的關系非常緊密,我們可以通過集合類來建立一個Iterator執行個體,ArrayList、LinkedList、Vector都有對它的實作。我們來看ArrayList是如何建立一個Iterator疊代器執行個體的。在此之前我們先來看看集合和疊代器之間的繼承關系。

Java疊代器Iterator

由于集合的關系相對來說比較複雜,在此我們主要看注釋部分,通過閱讀源代碼會發現ArrayList覆寫了AbstractList抽象類中的iterator方法并聲稱效果更佳,而LinkedList則沒有覆寫,由此可判斷ArrayList的iterator方法比LinkedList中的iterator方法更為高效。

我們直接看ArrayList裡中實作的iterator方法。

從代碼來看它傳回類一個Itr的對象執行個體,順着代碼看看這個Itr類是什麼。

原來Itr它是一個私有的内部類,實作Iterator接口。

我們來一行一行讀。在第3行中有一個modCount變量。跟蹤這個變量,發現這個變量有點意思:

發現有一個“transient”關鍵字,查閱資料發現這個關鍵字的意思是:表示一個域不是該對象序列化的一部分。意思是在對象被序列化時不包括這個變量,至于為什麼要這麼做呢,我們可以留下一個疑問。(JDk源碼注釋中是這麼說的:The modCount value that the iterator believes that the backing List should have. If this expectation is violated, the iterator has detected concurrent modification.英語太次隻能讀懂最後一句:如果這個期望是可見性的,那麼這個疊代器會檢測到有一個并發的修改。猜測是和并發多線程相關。)

hasnext的實作較為簡單:

next的實作:

在next方法中我們看到有一個checkForCommodification方法:

看來這個modCount變量确實是和并發相關,如果expectedModCount和modCount這兩個值不同,則抛出目前正在并發修改的異常。

最後我們來看remove方法的實作:

在remove方法中我們要格外注意,在第一句是檢測lastRet是否小于0,我們初始化了lastRet變量-1的值,這意味着,如果我們如果建立完Iterator執行個體後直接調用remove方法會抛出一個IllegalStateException異常,那怎麼才能正确調用呢?那就是在調用remove方法前先調用next方法,此時lastReturn通過cursor索引被指派,這個時候才能正确使用remove方法。同時它也會調用checkForCommodification方法做并發修改檢測。其實我們可以看到JDK源碼之是以寫到好,是因為它每個方法都做了很多的檢測,以確定在盡量多的場景下準确無誤地運作。今天關于Java的疊代器就通過JDK源碼簡單介紹,通過對源碼的閱讀能夠加深我們的了解,這還隻是簡單的閱讀,并沒有做很深的了解。最後,我們以為一個Iterator的例子結尾。

本文轉自xmgdc51CTO部落格,原文連結:http://blog.51cto.com/12953214/1942290 ,如需轉載請自行聯系原作者