Kotlin遍歷集合導(dǎo)致并發(fā)修改異常的原因和解決方法
各位android 老司機(jī)們,對(duì)于android 遍歷結(jié)合的時(shí)候,發(fā)生并發(fā)修改異常一定毫不陌生;
之前看到過(guò)一篇文章,
在阿里巴巴Java開(kāi)發(fā)手冊(cè)中,有這樣一條規(guī)定:

其實(shí),增強(qiáng)for循環(huán)也是Java給我們提供的一個(gè)語(yǔ)法糖,如果將以上代碼編譯后的class文件進(jìn)行反編譯(使用jad工具)的話,可以得到以下代碼:

1、原因:(其實(shí)我都不想在各位老司機(jī)面前再贅述這個(gè)了。-_-||)
這個(gè)異常產(chǎn)生的原因是,迭代器依賴(lài)于集合而存在,在判斷成功后,集合中添加了新的元素,而迭代器并不知道,所有就報(bào)錯(cuò)了。其實(shí)這個(gè)問(wèn)題說(shuō)的是:迭代器遍歷集合中的元素的時(shí)候,不要使用集合對(duì)象去修改集合中的元素。
翻看ArrayList源碼和iterator()方法的具體實(shí)現(xiàn),可以發(fā)現(xiàn)ArrayList繼承于集合抽象類(lèi)有一個(gè)成員變量modCount,在每次對(duì)元素進(jìn)行增刪改時(shí),相應(yīng)方法會(huì)將modCount++。而進(jìn)行遍歷iterator的next方法中首先會(huì)調(diào)用checkForComodification()方法,這個(gè)方法會(huì)對(duì)modCount和expectedModCount進(jìn)行比較,expectedModCount是iterator的成員變量,一開(kāi)始被賦值為modCount,兩者不等就會(huì)拋出并發(fā)修改的異常。
解決方案:迭代器遍歷的時(shí)候,可以通過(guò)迭代器修改集合中的元素,iterator類(lèi)中也有修改元素的方法,并在修改完成后重新將modCount賦值給expectedModCount,之后進(jìn)行next遍歷檢查就不會(huì)再報(bào)異常。

2、解決方法:
1、直接使用普通for循環(huán)進(jìn)行操作
用for 循環(huán)遍歷,然后直接用list 操作,eg:

2、foreach,或者Iterator 遍歷的,直接用Iterator 來(lái)操作
3、問(wèn)題復(fù)現(xiàn)
那么說(shuō)了這多,其實(shí)就是mapIndexed 這個(gè)方法,這個(gè)語(yǔ)法糖其實(shí)是基于Iterator來(lái)遍歷的。
所以,如果你要是在使用這個(gè)方式遍歷的過(guò)程中從集合中remove元素,那就會(huì)有并發(fā)修改異常產(chǎn)生 ;

我還是貪圖Kotlin 高級(jí)用法的甜頭,而忽視了細(xì)節(jié),導(dǎo)致問(wèn)題出現(xiàn),粗心大意,理解不深害死人。。
總結(jié)
到此這篇關(guān)于Kotlin遍歷集合導(dǎo)致并發(fā)修改異常的原因和解決方法的文章就介紹到這了,更多相關(guān)Kotlin遍歷集合并發(fā)異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android之內(nèi)置和外置sdcard路徑顯示并且寫(xiě)入數(shù)據(jù)的方法
今天小編就為大家分享一篇Android之內(nèi)置和外置sdcard路徑顯示并且寫(xiě)入數(shù)據(jù)的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Android冷啟動(dòng)優(yōu)化的3個(gè)小案例分享
為了提高App的冷啟動(dòng)耗時(shí),除了在常規(guī)的業(yè)務(wù)側(cè)進(jìn)行耗時(shí)代碼優(yōu)化之外,為了進(jìn)一步縮短啟動(dòng)耗時(shí),需要在純技術(shù)測(cè)做一些優(yōu)化探索,本期我們從類(lèi)預(yù)加載、Retrofit 、ARouter方面進(jìn)行了進(jìn)一步的優(yōu)化,感興趣的同學(xué)跟著小編一起來(lái)看看吧2023-07-07
Android中backgroundDimEnabled的作用
這篇文章主要介紹了Android中backgroundDimEnabled的作用的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10
Android自定義View實(shí)現(xiàn)垂直時(shí)間軸布局
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)垂直時(shí)間軸布局的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
解決android studio中使用monitor工具無(wú)法打開(kāi)data文件夾問(wèn)題
這篇文章主要介紹了解決android studio中使用monitor工具無(wú)法打開(kāi)data文件夾問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Android實(shí)現(xiàn)顏色選取圓盤(pán)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)顏色選取圓盤(pán),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android Jetpack組件中LiveData的優(yōu)劣
LiveData是Jetpack組件的一部分,更多的時(shí)候是搭配ViewModel來(lái)使用,相對(duì)于Observable,LiveData的最大優(yōu)勢(shì)是其具有生命感知的,換句話說(shuō),LiveData可以保證只有在組件(?Activity、Fragment、Service)處于活動(dòng)生命周期狀態(tài)的時(shí)候才會(huì)更新數(shù)據(jù)2023-04-04
Android通過(guò)自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
通過(guò)自定義ImageView控件,在xml布局里面調(diào)用自定的組件實(shí)現(xiàn)圖片的縮放。下面給大家分享實(shí)現(xiàn)代碼,感興趣的朋友一起看看吧2016-10-10

