Java——迭代器iterator詳解

一、Iterator的API

      關於Iterator主要有三個方法:hasNext()、next()、remove()

      hasNext:沒有指針下移操作,只是判斷是否存在下一個元素

      next:指針下移,返回該指針所指向的元素

      remove:刪除當前指針所指向的元素,一般和next方法一起用,這時候的作用就是刪除next方法返回的元素

 

二、Iterator原理

迭代器是將集合的數據放到一個容器中並排成一排,iterator有一個遊標,最初的時候,遊標在第一個元素前面,調用Iterator.next()是將遊標往後移一位,Iterator.hasNext()是判斷遊標後面還沒有可以迭代的元素。

 

三、爲什麼用迭代器?

因爲最初的時候你用for循環遍歷List,之後人家又要你遍歷Set,但是for循環無法遍歷Set,因爲Set是無序的(無法get值),所以後面就統一用迭代器遍歷集合了。

 

四、迭代器爲什麼不定義成一個類,而是一個接口?

假如迭代器是一個類,我們就可以創建該類的對象,然後調用該類的方法來遍歷集合。

但是,Java定義了很多的集合類,他們的數據結構不相同,所以他們存儲的方式和遍歷的方法也應該是不相同的。所以最終就沒有定義迭代器類。

而無論你是哪種集合,你都應該具備獲取元素的操作。並且,最好輔助於判斷功能,這樣先判斷再獲取,就不會出錯。也就是說,判斷和獲取功能應該是集合所具備的,而因爲不同集合的數據結構不一樣,所以他們的判斷方式也不一樣。我們把這兩種功能抽象出來爲,不提供具體實現,就是接口。

 

五、如何實現迭代器?

在真正的具體類中,以內部類的方式體現出來。

每個集合類內部都含有一個內部類,用來實現Iterator接口。集合類的iterator方法就是在獲取內部類對象(迭代器對象),然後通過該對象調用hashNext和next方法實現遍歷。-

class ArrayList{
    public Iterator<E> iterator(){return new Itr();}
    class Itr implements Iterator{
        public hasNext(){……}//重寫這兩個方法,實現元素遍歷
        public next(){……}
    }
}

通過內部類,我們纔可以使用諸如list.iterator().hasNext()這樣的方法。

 

六、迭代器迭代順序

HashMap按鍵的順序,HashSet按hashCode的順序。

 

七、爲什麼被迭代的對象不允許被改變?

用迭代器本身刪除是可以的,但是在迭代器中對集合本身進行刪除就不行了, 對於這種莫名其妙的問題,我們從源碼入手

我們注意到expectedModCount這個字段,他的初始值是等於modCount的。 而當我們不通過迭代器對集合進行增刪時,modCount的值會發生改變,最後拋出異常

那麼爲什麼要這樣呢? 

迭代器是工作在一個獨立的線程中,並且擁有一個mutex鎖,就是說iterator在工作的時候,是不允許被迭代的對象被改變的。(至於爲什麼不允許改變)

iterator被創建的時候建立一個內存索引表(單鏈表),這個索引表指向原來的對象,當原來的對象數量改變的時候,這個索引表的內容沒有同步改變,所以當索引指針往下移的時候,便找不到要迭代的對象,於是錯誤。

List、Set等是動態的,可變對象的數量的數據結構,但是iterator則是單向不可變的,只能順序讀取,不能逆序操作的數據結構,當iterator指向的原始數據發生變化時,iterator自己就迷失了方向。

注:正是因爲這個原因,一定要注意線程安全問題。

 

參考博客:

https://blog.csdn.net/liyancheng984807972/article/details/9744949

https://blog.csdn.net/hellowordapi/article/details/54233590

https://blog.csdn.net/xiakexiaohu/article/details/73017210

https://blog.csdn.net/shuaishuai3409/article/details/52210255

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章