首頁  >  文章  >  Java  >  Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

王林
王林轉載
2023-04-27 15:40:171717瀏覽

    一、Iterator與foreach的區別

    • 多態差異(foreach底層就是Iterator)

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    ##Iterator是一個介面類型,他不關心集合或陣列的類型;

    #for和foreach都需要先知道集合的類型,甚至是集合內元素的類型;

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?1.為啥說foreach底層就是Iterator

    所寫的程式碼:

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    反編譯程式碼:

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?二、foreach與iterator時remove的差別

    先來看

    阿里java開發手冊

    但1的時候不會報錯,2的時候就會報錯(java.util.ConcurrentModificationException)




    首先來看看ArrayList中iterator方法的實作:

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?呼叫了new Itr(),產生Itr類別(迭代器)。此時會給Itr的三個參數初始化。


    cursor代表下一次的索引位置(開始是0)

    size是集合的大小(2)

    拋出異常類別

    next方法()的時候會檢查checkForComodification是否相等

    modCount修改計數(每次add和remove都會1)expectedModCount期望的最大計數

    1.remove操作源碼分析

    首先來看一下刪除“2”的情況:

    第一次迴圈:

    因為此時的modCount和expectedModCount都為2(因為add了兩次所以modCount為2),所以第一次迴圈中不會拋出例外,拋出異常都是發生在不是第一次循環的情況。在next方法走完後,foreach迴圈方法體中的remove方法的if條件判斷不滿足,就結束了本次迴圈。

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?第二次循環:

    第二次循環的hasNext和next方法都是能成功走完的,在這之後會進入到foreach循環方法體中的remove方法中,進行刪除元素。而此時的size-1變成為了1。在remove方法中的fastRemove方法中,會對modCount 1,也就變成了3。

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    ######第三次迴圈:#########然後會走入到第三次迴圈中的hasNext方法。依照正常的情況下該方法是會回傳false的,但因為此時的size已經變成了1,而此時的cursor為2(cursor代表下一次的索引位置),所以兩者不等,錯誤地傳回了true,所以會繼續走入到next方法中的checkForComodification方法中,判斷此時的modCount和expectedModCount是否相等。因為此時的modCount已經變成了3,和expectedModCount的值為2不等,所以在此拋出了ConcurrentModificationException異常。 ######再來看一下刪除「1」的時候為什麼不會拋出例外:###### #########第一次循環:######### #同上,此時的modCount和expectedModCount都為2,所以第一次迴圈中的hasNext和next方法都不會拋異常。在這之後會進入foreach迴圈方法體中的remove方法中,進行刪除元素。同上,size-1變成為了1,而modCount 1變成為了3。 #########第二次循環:#########在第二個循環的hasNext方法中,此時的cursor為1,而size也是1,兩者相等。所以hasNext方法回傳false,就跳出了foreach循環,不會走到隨後的next方法中,也就不會拋出異常。 ######2.源碼步驟#########第一次#########第①句呼叫iterator(),##################################################################################################### ####呼叫了new Itr(),產生Itr類別(迭代器)。此時會給Itr的三個參數初始化。 ############

    此時expectedModCount == modCount == 2(因為list調動了add方法,add方法會對modCount實作操作)
    第②句呼叫下面hasNext()方法,傳回下一個要存取元素的下標cursor,因為是第一次循環,所以cursor為0,size為2 (0 != 2 true)
    第③句呼叫next()方法,foreach循環方法體中的remove方法的if條件判斷不滿足,就結束了本次循環

    第二次

    第②句呼叫下面hasNext()方法,傳回下一個要存取元素的下標cursor,第二次循環,所以cursor為1,
    size還是為2 (1 != 2 true)
    第③句呼叫next()方法,正常取值,取到第一個元素"2";
    第④句呼叫remove()方法,成功為list刪除元素。注意,在呼叫remove方法的時候,有modCount 。所有此時,modCount3,expectedModCount2,size1

    第三次

    第②句呼叫下面hasNext()方法,傳回下一個要存取元素的下標cursor ,第二次循環,所以cursor為2,size為1
    第③句呼叫next()方法,注意,在next()方法中第一句話就是呼叫checkForComodification();由於modCount(3) ! = expectedModCount(2),所以就拋了異常。

    3.為啥都是底層都是iterator,為啥foreach會報錯

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    當迴圈結束的時候,while (iterator.hasNext() ) 會檢查是否有下個元素存在,在remove刪除2完成後,下次進入cursor還是1,size也是1.
    foreach的話,刪除remove2之後,下次進入cursor是2,size是1,所以返回false,要走next方法,然後,進行檢查,modCount=3,而expectedModCount=2

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    ##三、查看原始碼方法

    如果查看iterator下的ArrayList

    Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?

    以上是Java ArrayList遍歷時使用foreach和iterator刪除元素的差異是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除