最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

Iterator接口使用時并發(fā)修改異常的解決過程

2023-11-06 18:42 作者:袁庭新  | 我要投稿

相信很多小伙伴通過對JavaSE基礎(chǔ)內(nèi)容的學(xué)習(xí),已經(jīng)對List集合有了較好的掌握,那接著就請大家跟著袁老師來回顧一下List相關(guān)的內(nèi)容吧。大家知道,我們在遍歷List集合時,通常會使用Iterator接口來迭代集合中的元素。

但是,如果我們對Iterator接口使用不當(dāng),就可能會導(dǎo)致并發(fā)修改異常,即java.util.ArrayList$Itr.checkForComodification異常。那這個checkForComodification異常到底是如何產(chǎn)生的呢?接下來就請大家來跟隨袁老師的步伐,一點點揭開它的神秘面紗吧。

01?什么異常

首先,袁老師簡單帶大家回顧一下異常的相關(guān)知識。我們舉個例子好,就好比人人都希望自己身體健康,遇到的事情都能順利解決,但在實際生活中總會遇到各種狀況,比如感冒發(fā)燒,工作時電腦藍屏、死機等。

同樣,在程序運行的過程中,也會發(fā)生各種非正常的狀況。例如,程序運行時磁盤空間不足、網(wǎng)絡(luò)連接中斷、被裝載的類不存在等。針對這種情況, Java語言給我們引入了異常處理機制,以異常類的形式對這些非正常情況進行封裝,利用異常處理機制對程序運行時發(fā)生的各種問題進行處理。

接下來我們通過一個案例來認(rèn)識一下什么是異常。

上述代碼的運行結(jié)果如下圖所示:

從運行結(jié)果可以看出,這個程序發(fā)生了算術(shù)異常(ArithmeticException),該異常是由于調(diào)用divide()方法時傳入了參數(shù)0,運算時出現(xiàn)了被0除的情況。該異常發(fā)生后,程序就會立即結(jié)束,無法繼續(xù)向下執(zhí)行。

02?Iterator接口

我們在程序開發(fā)中,經(jīng)常需要遍歷集合中的所有元素。針對這種需求,Java專門提供了一個Iterator接口。Iterator接口也是集合中的一員,但它與Collection、Map接口有所不同。Collection接口與Map接口主要用于存儲元素,而Iterator則主要用于迭代訪問(即遍歷)Collection中的元素,因此Iterator對象也被稱為迭代器。

接下來我們再通過一個案例,來學(xué)習(xí)如何使用Iterator迭代集合中的元素。

當(dāng)遍歷元素時,首先通過調(diào)用ArrayList集合的iterator()方法來獲得迭代器對象;然后使用hasNext()方法判斷集合中是否存在下一個元素。如果存在,則調(diào)用next()方法將元素取出,否則說明已到達了集合末尾,停止遍歷元素。需要注意的是,在通過next()方法獲取元素時,我們必須保證要獲取的元素存在,否則,就會拋出NoSuchElementException異常。

Iterator迭代器在遍歷集合時,內(nèi)部采用指針的方式來跟蹤集合中的元素,為了讓初學(xué)者更好地理解迭代器的工作原理,接下來袁老師再通過一個圖例來演示Iterator對象迭代元素的過程。

上圖中,我們在調(diào)用Iterator的next()方法之前,迭代器的索引位于第一個元素之前,不指向任何元素。當(dāng)?shù)谝淮握{(diào)用迭代器的next()方法后,迭代器的索引會向后移動一位,指向第一個元素并將該元素返回。當(dāng)再次調(diào)用next()方法時,迭代器的索引會指向第二個元素并將該元素返回。然后以此類推,直到hasNext()方法返回false,表示到達了集合的末尾,終止對元素的遍歷。

通過迭代器獲取ArrayList集合中的元素時,這些元素的類型都是Object類型。如果我們想獲取到特定類型的元素,則需要進行對數(shù)據(jù)類型強制轉(zhuǎn)換。

通過袁老師對上述案例的分析,想必各位小伙伴對如何使用Iterator接口來迭代集合中的元素,已經(jīng)掌握的很深入了。那么如果我們在使用Iterator迭代集合元素時,如果使用不當(dāng)就可能會產(chǎn)生并發(fā)修改的異常,下面就再請大家來跟隨袁老師的思路,咱們一塊兒來探索這個問題。

03?并發(fā)修改異常

在使用Iterator迭代器對集合中的元素進行迭代時,如果我們調(diào)用了集合對象的remove()方法去刪除元素之后,繼續(xù)使用迭代器遍歷元素,就會出現(xiàn)異常。

下面我們通過一個案例來演示這種異常。假設(shè)在一個集合中存儲了學(xué)校里所有學(xué)生的姓名,由于一個名為“張三”的學(xué)生中途轉(zhuǎn)學(xué),這時就需要在迭代集合時找出該元素并將其刪除,具體代碼如下。

上述程序在運行時出現(xiàn)了并發(fā)修改異常ConcurrentModificationException,這個異常是由迭代器對象拋出的。而出現(xiàn)該異常的原因是集合在迭代器運行期間刪除了元素,這會導(dǎo)致迭代器預(yù)期的迭代次數(shù)發(fā)生改變,導(dǎo)致迭代器的結(jié)果不準(zhǔn)確。

要解決上述問題,我們可以采用兩種方式,下面袁老師會對這兩種方式分別進行介紹。

第一種方式:從業(yè)務(wù)邏輯上講,我們只想將姓名為“張三”的學(xué)生刪除,至于后面還有多少學(xué)生并不關(guān)心。所以我們只需找到該學(xué)生跳出循環(huán)不再迭代即可,也就是可以在第12行代碼下面增加一個break語句,代碼如下:

第二種方式:如果我們需要在迭代集合期間對集合中的元素進行刪除,可以使用迭代器本身的刪除方法,將第12行代碼替換成it.remove()方法,即可解決這個問題:

由運行結(jié)果可知,學(xué)員“張三”確實被刪除了,且沒有出現(xiàn)異常。因此我們可以得出結(jié)論,當(dāng)調(diào)用迭代器對象的remove()方法來刪除元素,會導(dǎo)致迭代次數(shù)的變化,這對于迭代器對象本身來講是可預(yù)知的。

04?回顧總結(jié)

關(guān)于Iterator接口并發(fā)修改異常的解析,袁老師就給大家介紹到這里,最后我們再來回顧下這一小節(jié)的主要內(nèi)容。

首先,袁老師給大家介紹了什么是異常;然后,介紹了Iterator是如何遍歷List集合的;最后,袁老師給大家介紹了使用Iterator進行集合元素遍歷時,可能產(chǎn)生的并發(fā)修改問題,以及如何防止該問題的產(chǎn)生。

好了,本文的內(nèi)容袁老師就給大家介紹到這里了,你學(xué)會了嗎?關(guān)注「袁庭新」,干貨天天都不斷!


Iterator接口使用時并發(fā)修改異常的解決過程的評論 (共 條)

分享到微博請遵守國家法律
邛崃市| 樟树市| 渝中区| 铜川市| 定襄县| 乳山市| 东乡县| 枣强县| 洛浦县| 云龙县| 南昌市| 开江县| 安徽省| 余庆县| 荥经县| 名山县| 麦盖提县| 呼图壁县| 宜丰县| 黔江区| 威宁| 石河子市| 关岭| 泸定县| 安乡县| 临泉县| 福泉市| 彩票| 曲阜市| 镇巴县| 剑河县| 亚东县| 陇南市| 周宁县| 沂水县| 阜平县| 溧水县| 金门县| 大悟县| 孟津县| 新泰市|