1. 程式人生 > >移除collection中元素的註意事項(應用collection.remove移除元素造成的錯誤)

移除collection中元素的註意事項(應用collection.remove移除元素造成的錯誤)

com 試用 原因 錯誤 iterator 兩種 6.0 進行 書寫

大家已知的遍歷collection的方式通常有兩種,一種是for(object key :collection<object>),一種是應用iterator。這兩種方式都能對於collection進行遍歷,但是當要移除collection中的部分元素的時候,使用for對於collection進行遍歷,想要移除元素,就要調用collection的remove操作,這樣可能會給collection的遍歷帶來bug,而且這個錯誤及其不容易被發現,下面我們就簡要介紹一下造成這種錯誤的原因:

例如一個ArrayList<String>,其包含的元素由["6.045","6.005","6.813"],然後我們寫一個方法要求去除這個list中所有6.開頭的String。首先我們嘗試用collection.remove進行移除。程序如下:

技術分享圖片

按我們的初衷,這個函數執行完之後collection應該為空,但是實際並非這種情況,這個函數執行完之後,collection還有6.005存在。這是什麽原因呢?下面我們用snapshot進行一定的介紹:

開始的時候snapshot應該屬於這種情況

技術分享圖片

方法臊面list的第一個元素,然後調用其collection.remove方法之後,由於list會進行動態調整數據的狀態變成了

技術分享圖片

然而此時,遍歷collection操作認為第0號元素的遍歷已經完成,接著他就開始進行對於第1號元素的遍歷,這就造成了6.005沒有被遍歷到,因此也就不會被程序移除。這是一個很難被發現的bug,同時bug出現的幾率也不是很大,和數據的組成有關,如果移除的數據後面的數據恰好是不需要的數據,那麽這種方式就不會顯示出任何錯誤,如果是需要的數據,這種方式就會造成這個需要的數據不能夠被訪問。

技術分享圖片

其實,我們在使用iterator的過程中,iterator接口已經為我們提供了remove操作,應用iterator提供的remove操作移除collection中的元素就不會造成這種錯誤:

技術分享圖片

這種方式對collection中的元素進行移除就不會產生任何問題,這是因為iterator的開發者早就已經認識到了這個問題,他在書寫iterator.remove 的過程中對於這個問題進行了解決。因此使用iterator.remove移除collection中的元素不會造成任何錯誤。

移除collection中元素的註意事項(應用collection.remove移除元素造成的錯誤)