這篇文章將為大家詳細(xì)講解有關(guān)如何進(jìn)行Iterator中的Itr類的分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
創(chuàng)新互聯(lián)建站專注于企業(yè)成都全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、安丘網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5響應(yīng)式網(wǎng)站、購(gòu)物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為安丘等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
好,我們言歸正傳,來(lái)看看他為什么錯(cuò),錯(cuò)在哪里?
先看代碼:
1
哪里錯(cuò)了
很明顯,他是在第36行報(bào)錯(cuò)的,也就是在遍歷完數(shù)值為3的數(shù)據(jù)報(bào)錯(cuò)的。讓我們往前順順,為什么遍歷完第二個(gè)元素就報(bào)錯(cuò)了,因?yàn)樗闅v完數(shù)值為3的數(shù)據(jù)后,往list里面增加了一個(gè)數(shù)值為12的數(shù)據(jù)。
那我們把遍歷里面的if判斷去掉試試,答案是肯定正確的。那我們找到了原因,也就是在遍歷的時(shí)候添加了一個(gè)元素,所以導(dǎo)致了他錯(cuò)誤。
2
錯(cuò)在哪里
我們看一下ArrayList中的源碼,他在add方法里面做了什么,導(dǎo)致了他在遍歷的時(shí)候報(bào)錯(cuò)。
圖一:
圖二:
圖三:
圖四:
上面的四幅圖都是層級(jí)調(diào)用的關(guān)系, 也就是在執(zhí)行確定按鈕的時(shí)候,先確定list數(shù)組的大小,ensureCapacityInternal方法,如果為空數(shù)組,就取ArrayList中的常量DEFAULT_CAPACITY作為容器大小,然后增加修改次數(shù)modCount,最后比較最小容量和數(shù)組長(zhǎng)度的大小,考慮擴(kuò)容的情況。從剛才的敘述來(lái)看,他只是增加修改次數(shù)modCount,并考慮是否擴(kuò)容。
那我們來(lái)看一下modCount是什么,以及在哪里使用了,讓我們回到這個(gè)題目。
在第33行,在list數(shù)組上定義了一個(gè)iterator,我們跟到源碼看一下
也就是他創(chuàng)建了一個(gè)Itr類,而這個(gè)類包括cursor,lastRet,expectedModCount三個(gè)變量,hasNext,next,remove三個(gè)方法。
那么我們來(lái)科普一下這三個(gè)變量分別代表什么意思,cursor表示下一個(gè)要訪問(wèn)元素的下標(biāo),lastRet表示上一個(gè)訪問(wèn)元素的下標(biāo),expectedModCount表示期望修改次數(shù)。
next方法和remove方法在開(kāi)始的地方都調(diào)用了checkForComodification方法,那該方法里面就是判斷modCount和expectedModCount次數(shù)是否一樣,如果不一樣,就拋出異常,很明顯,我們開(kāi)始運(yùn)行代碼時(shí)的報(bào)錯(cuò)信息與該異常相吻合,那其實(shí)我們就知道了他其實(shí)是在該處拋出的異常信息導(dǎo)致程序報(bào)錯(cuò),那也就是modCount和expectedModCount是不一樣的。
3
斷點(diǎn)調(diào)試
下面我們從頭開(kāi)始整理一下整個(gè)流程,斷點(diǎn)調(diào)試一下整個(gè)代碼。
首先他先構(gòu)造一個(gè)數(shù)組,并往里面增加了1,3,2數(shù)據(jù),在上面已經(jīng)看過(guò)add方法里面有什么,在add方法里面有增加modCount的值,所以在這里modCount已經(jīng)為3啦。接著定義了一個(gè)iterator,剛才我們知道啦其實(shí)也就是新建了一個(gè)Itr類,那我們看下在33行結(jié)束后,iterator的值是什么。
下一個(gè)要訪問(wèn)的下標(biāo)cursor為0,上一個(gè)要訪問(wèn)的下標(biāo)lastRet為-1,預(yù)計(jì)期望修改次數(shù)expectedModCount為3,其實(shí)也就是等于他的數(shù)組大小size,也就是3。
接著進(jìn)入35行開(kāi)始迭代數(shù)組,執(zhí)行hasNext方法,cursor為0,不等于size,為true,繼續(xù)執(zhí)行next方法,先判斷modCount(也就是3)是否與expectedModCount(也就是3)相等,答案是相等的,再輸出該數(shù)值1。
接著再進(jìn)入35行開(kāi)始迭代數(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。
接著再進(jìn)入35行開(kāi)始迭代數(shù)組,執(zhí)行hasNext方法,cursor為2,不等于size,為true,繼續(xù)執(zhí)行next方法,先判斷modCount(也就是4)是否與expectedModCount(也就是3)相等,答案是不相等的,拋出異常。
整個(gè)流程結(jié)束。
ArrayList是不能在遍歷的時(shí)候,在對(duì)其進(jìn)行修改操作的,包括增加和刪除。也就是線程不安全的。如果在遍歷的過(guò)程中有其他線程修改了lsit,則會(huì)拋出異常,這就是fast-fail(快速失敗策略),這一策略在源碼中的體現(xiàn)就是在next方法的時(shí)候,會(huì)調(diào)用checkForComodification方法,通過(guò)比較modCount和expectedModCount兩者的是否相等,判斷是否在遍歷的時(shí)候,有進(jìn)行修改操作,從而確定是否要拋出異常。那么在需要保證數(shù)組在遍歷的時(shí)候不進(jìn)行修改操作的時(shí)候,可以優(yōu)先使用iterator來(lái)遍歷。
關(guān)于如何進(jìn)行Iterator中的Itr類的分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
本文題目:如何進(jìn)行Iterator中的Itr類的分析
文章鏈接:http://aaarwkj.com/article20/pjcijo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)公司、企業(yè)建站、服務(wù)器托管、響應(yīng)式網(wǎng)站、品牌網(wǎng)站建設(shè)、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)