foreach遍歷list刪除元素報錯了?

2021-10-10 17:25:50 字數 2962 閱讀 6231

記得老師之前說過:遍歷list時,不允許改變其結構,否則會拋異常。

今天在複習list時,我不信這個「邪」決定試一試!然後,有了如下的「心得體會」!

先來個常規操作:

public

class

iteratordemo

} system.out.

println

(list);}

}

不出意料,報錯了!

再試一次!這次換個元素,換成倒數第二個元素試試看!

for

(string next:list)

}

哎喲,沒有報錯還得出來正確結果,怎麼肥四???

再討論這個問題前,我們先來看一看foreach遍歷的原理。

foreach本質上建立了迭代器,利用iterator實現遍歷。

即:

iterator

it =list.

iterator()

;while

(it.

hasnext()

)}

那這…和拋異常有啥關係呢?來看看原始碼怎麼說!

private

class

itrimplements

iterator

//1.

public

boolean

hasnext()

//2.

public e next()

//3.

public

void

remove()

catch

(indexoutofbound***ception ex)

}//4.

final

void

checkforcomodification()

}

好傢伙!看完更懵圈了!

那我們拆開來看看!

首先回答:為什麼遍歷list時,刪除元素會拋異常?

仔細看報錯資訊,會發現丟擲的異常為:checkforcomodification()

原始碼如下:

final

void

checkforcomodification()

modcount:修改次數

當list調動add方法時,add方法會對modcount實現++操作,如上例,共呼叫了add()4次,

則modcount=4。

而在迭代器初始化過程中會將這個值賦給迭代器的expectedmodcount

則此時:modcount==expectedmodcount==4

然鵝,

當進行一次刪除操作,即,對list進行了一次修改,則modcount+1,此時,modcount==5

expectedmodcount依然為 4,因為:modcount != expectedmodcount,所以丟擲異常!

好了,現在明白了為啥拋異常,那咱再來看看為啥不拋異常!

迭代時實際上呼叫了兩個方法,即:hasnext()和next()

並且我們可以看到,拋異常的處理是在next()方法中。

再看看原始碼:

//1.

public

boolean

hasnext()

//2.

public e next()

所以,不拋異常的最佳方法,就是不進hasnext()方法,前提是:刪除的元素為倒數第二個元素!

cursor:儲存當前iterator的位置資訊,從0開始。

其實很簡單,讓cursor == size即可,當cursor == size時,返回false。也就是說:當next()方法接收到hasnext()發來的資訊,得知,沒有下乙個元素了,就不再進行處理。

又為啥是倒數第二個元素呢?

因為cursor記錄著當前的位置資訊,

當`cursor == size`時,就可以全身而退了!

舉例說明:

刪除倒數第二個元素,cursor=3,而size-1,即size=3。當再呼叫hasnext()判斷的時候,cursor==sizereturn false,自然就不會執行next()方法,而是直接執行remove()操作刪除元素後,直接退出迴圈,也就不會走到最後拋異常環節了。

1.foreach遍歷的本質是建立了乙個迭代器。

2.遍歷list時,刪除元素會報錯,但刪除倒數第二個元素就不會。

3.學會看原始碼是個好技能!

(上述所有不當之處,還請批評指正!)

List集合遍歷刪除元素

j a三種遍歷如何進行list的遍歷刪除 1 for迴圈 常見錯誤寫法 由於下標問題達不到想要效果 for int i 0 i應該改為 倒序操作避免下標問題 int size list.size for int i size 1 i 0 i 2 增強for迴圈 foreach迴圈 常見錯誤 會丟擲c...

forEach 同時遍歷兩個List方法的說明

有時我們拿到兩個長度相等的list,不想封裝到一起,又想同時遍歷,就需要用到下面的方法。這裡需要遍歷兩個list gallerylist 和 classlist 第乙個 gallerylist 正常使用常規方法即可。第二個 classlist 我們使用 varstatus 這個關鍵屬性,那麼當值為 ...

關於foreach遍歷

農夫 14 49 12 foreach type identifier in expression 求工作 14 50 00 for iterable type iterable element iterable 告訴我 括號裡的格式 農夫 14 51 09 for 型別 變數 要遍歷的物件 下文抄...