溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何進行Iterator中的Itr類的分析

發(fā)布時間:2021-12-08 15:13:20 來源:億速云 閱讀:149 作者:柒染 欄目:大數(shù)據(jù)

這篇文章將為大家詳細(xì)講解有關(guān)如何進行Iterator中的Itr類的分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。


好,我們言歸正傳,來看看他為什么錯,錯在哪里?

先看代碼:

如何進行Iterator中的Itr類的分析

1

哪里錯了

很明顯,他是在第36行報錯的,也就是在遍歷完數(shù)值為3的數(shù)據(jù)報錯的。讓我們往前順順,為什么遍歷完第二個元素就報錯了,因為他遍歷完數(shù)值為3的數(shù)據(jù)后,往list里面增加了一個數(shù)值為12的數(shù)據(jù)。

那我們把遍歷里面的if判斷去掉試試,答案是肯定正確的。那我們找到了原因,也就是在遍歷的時候添加了一個元素,所以導(dǎo)致了他錯誤。

2

錯在哪里

 我們看一下ArrayList中的源碼,他在add方法里面做了什么,導(dǎo)致了他在遍歷的時候報錯。

圖一:

如何進行Iterator中的Itr類的分析

圖二:

如何進行Iterator中的Itr類的分析

圖三:

如何進行Iterator中的Itr類的分析

圖四:

如何進行Iterator中的Itr類的分析

上面的四幅圖都是層級調(diào)用的關(guān)系, 也就是在執(zhí)行確定按鈕的時候,先確定list數(shù)組的大小,ensureCapacityInternal方法,如果為空數(shù)組,就取ArrayList中的常量DEFAULT_CAPACITY作為容器大小,然后增加修改次數(shù)modCount,最后比較最小容量和數(shù)組長度的大小,考慮擴容的情況。從剛才的敘述來看,他只是增加修改次數(shù)modCount,并考慮是否擴容。

那我們來看一下modCount是什么,以及在哪里使用了,讓我們回到這個題目。

如何進行Iterator中的Itr類的分析

在第33行,在list數(shù)組上定義了一個iterator,我們跟到源碼看一下

如何進行Iterator中的Itr類的分析

也就是他創(chuàng)建了一個Itr類,而這個類包括cursor,lastRet,expectedModCount三個變量,hasNext,next,remove三個方法。

那么我們來科普一下這三個變量分別代表什么意思,cursor表示下一個要訪問元素的下標(biāo),lastRet表示上一個訪問元素的下標(biāo),expectedModCount表示期望修改次數(shù)。

next方法和remove方法在開始的地方都調(diào)用了checkForComodification方法,那該方法里面就是判斷modCount和expectedModCount次數(shù)是否一樣,如果不一樣,就拋出異常,很明顯,我們開始運行代碼時的報錯信息與該異常相吻合,那其實我們就知道了他其實是在該處拋出的異常信息導(dǎo)致程序報錯,那也就是modCount和expectedModCount是不一樣的。

如何進行Iterator中的Itr類的分析

3

斷點調(diào)試

下面我們從頭開始整理一下整個流程,斷點調(diào)試一下整個代碼。

如何進行Iterator中的Itr類的分析

首先他先構(gòu)造一個數(shù)組,并往里面增加了1,3,2數(shù)據(jù),在上面已經(jīng)看過add方法里面有什么,在add方法里面有增加modCount的值,所以在這里modCount已經(jīng)為3啦。接著定義了一個iterator,剛才我們知道啦其實也就是新建了一個Itr類,那我們看下在33行結(jié)束后,iterator的值是什么。

如何進行Iterator中的Itr類的分析
  1. 下一個要訪問的下標(biāo)cursor為0,上一個要訪問的下標(biāo)lastRet為-1,預(yù)計期望修改次數(shù)expectedModCount為3,其實也就是等于他的數(shù)組大小size,也就是3。

  2. 接著進入35行開始迭代數(shù)組,執(zhí)行hasNext方法,cursor為0,不等于size,為true,繼續(xù)執(zhí)行next方法,先判斷modCount(也就是3)是否與expectedModCount(也就是3)相等,答案是相等的,再輸出該數(shù)值1。

  3. 接著再進入35行開始迭代數(shù)組,執(zhí)行hasNext方法,cursor為1,不等于size,為true,繼續(xù)執(zhí)行next方法,先判斷modCount(也就是3)是否與expectedModCount(也就是3)相等,答案是相等的,再輸出該數(shù)值3。此處注意有if判斷。里面有add方法,modCount是要加1的,現(xiàn)在modCount已經(jīng)變成了4。

  4. 接著再進入35行開始迭代數(shù)組,執(zhí)行hasNext方法,cursor為2,不等于size,為true,繼續(xù)執(zhí)行next方法,先判斷modCount(也就是4)是否與expectedModCount(也就是3)相等,答案是不相等的,拋出異常。

  5. 整個流程結(jié)束。

ArrayList是不能在遍歷的時候,在對其進行修改操作的,包括增加和刪除。也就是線程不安全的。如果在遍歷的過程中有其他線程修改了lsit,則會拋出異常,這就是fast-fail(快速失敗策略),這一策略在源碼中的體現(xiàn)就是在next方法的時候,會調(diào)用checkForComodification方法,通過比較modCount和expectedModCount兩者的是否相等,判斷是否在遍歷的時候,有進行修改操作,從而確定是否要拋出異常。那么在需要保證數(shù)組在遍歷的時候不進行修改操作的時候,可以優(yōu)先使用iterator來遍歷。

關(guān)于如何進行Iterator中的Itr類的分析就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI