2022-12-15
集合 元素 代器 iterator
Iterator接口介紹
在程序開發(fā)中,經(jīng)常需要遍歷集合中的所有元素。針對這種需求,Java專門提供了一個(gè)接口Iterator。Iterator接口也是集合中的一員,但它與Collection、Map接口有所不同。Collection接口與Map接口主要用于存儲元素,而Iterator主要用于迭代訪問(即遍歷)Collection中的元素,因此Iterator對象也被稱為迭代器。
接下來通過一個(gè)案例學(xué)習(xí)如何使用Iterator迭代集合中的元素。
Java |
當(dāng)遍歷元素時(shí),首先通過調(diào)用ArrayList集合的iterator()方法獲得迭代器對象;然后使用hasNext()方法判斷集合中是否存在下一個(gè)元素,如果存在,則調(diào)用next()方法將元素取出,否則說明已到達(dá)了集合末尾,停止遍歷元素。需要注意的是,在通過next()方法獲取元素時(shí),必須保證要獲取的元素存在,否則,會拋出NoSuchElementException異常。
Iterator迭代器對象在遍歷集合時(shí),內(nèi)部采用指針的方式來跟蹤集合中的元素,為了讓初學(xué)者能更好地理解迭代器的工作原理,接下來通過一個(gè)圖例演示Iterator對象迭代元素的過程。
上圖中,在調(diào)用Iterator的next()方法之前,迭代器的索引位于第一個(gè)元素之前,不指向任何元素,當(dāng)?shù)谝淮握{(diào)用迭代器的next()方法后,迭代器的索引會向后移動(dòng)一位,指向第一個(gè)元素并將該元素返回,當(dāng)再次調(diào)用next()方法時(shí),迭代器的索引會指向第二個(gè)元素并將該元素返回,以此類推,直到hasNext()方法返回false,表示到達(dá)了集合的末尾,終止對元素的遍歷。
通過迭代器獲取ArrayList集合中的元素時(shí),這些元素的類型都是Object類型,如果想獲取到特定類型的元素,則需要進(jìn)行對數(shù)據(jù)類型強(qiáng)制轉(zhuǎn)換。
并發(fā)修改異常
在使用Iterator迭代器對集合中的元素進(jìn)行迭代時(shí),如果調(diào)用了集合對象的remove()方法去刪除元素之后,繼續(xù)使用迭代器遍歷元素,會出現(xiàn)異常。接下來通過一個(gè)案例演示這種異常。假設(shè)在一個(gè)集合中存儲了學(xué)校所有學(xué)生的姓名,由于一個(gè)名為“張三”的學(xué)生中途轉(zhuǎn)學(xué),這時(shí)就需要在迭代集合時(shí)找出該元素并將其刪除,具體代碼如下。
|
上述程序在運(yùn)行時(shí)出現(xiàn)了并發(fā)修改異常ConcurrentModificationException。這個(gè)異常是迭代器對象拋出的,出現(xiàn)異常的原因是集合在迭代器運(yùn)行期間刪除了元素,會導(dǎo)致迭代器預(yù)期的迭代次數(shù)發(fā)生改變,導(dǎo)致迭代器的結(jié)果不準(zhǔn)確。
要解決上述問題,可以采用兩種方式,下面分別介紹。
第一種方式:從業(yè)務(wù)邏輯上講只想將姓名為“張三”的學(xué)生刪除,至于后面還有多少學(xué)生并不需要關(guān)心,只需找到該學(xué)生后跳出循環(huán)不再迭代即可,也就是在第12行代碼下面增加一個(gè)break語句,代碼如下:
Java |
第二種方式:如果需要在集合的迭代期間對集合中的元素進(jìn)行刪除,可以使用迭代器本身的刪除方法,將第12行代碼替換成it.remove()即可解決這個(gè)問題:
Java |
由運(yùn)行結(jié)果可知,學(xué)員“張三”確實(shí)被刪除了,并且沒有出現(xiàn)異常。因此可以得出結(jié)論,調(diào)用迭代器對象的remove()方法刪除元素所導(dǎo)致的迭代次數(shù)變化,對于迭代器對象本身來講是可預(yù)知的。
開班時(shí)間:2021-04-12(深圳)
開班盛況開班時(shí)間:2021-05-17(北京)
開班盛況開班時(shí)間:2021-03-22(杭州)
開班盛況開班時(shí)間:2021-04-26(北京)
開班盛況開班時(shí)間:2021-05-10(北京)
開班盛況開班時(shí)間:2021-02-22(北京)
開班盛況開班時(shí)間:2021-07-12(北京)
預(yù)約報(bào)名開班時(shí)間:2020-09-21(上海)
開班盛況開班時(shí)間:2021-07-12(北京)
預(yù)約報(bào)名開班時(shí)間:2019-07-22(北京)
開班盛況Copyright 2011-2023 北京千鋒互聯(lián)科技有限公司 .All Right 京ICP備12003911號-5 京公網(wǎng)安備 11010802035720號