@Eran已經explained如何解決這個問題更好。我將解釋爲什麼ConcurrentModificationException
發生。由於您正在修改流源,因此發生ConcurrentModificationException
。您的Map
很可能是HashMap
或TreeMap
或其他非併發地圖。我們假設這是一個HashMap
。每個流都支持Spliterator
。如果spliterator沒有IMMUTABLE
和CONCURRENT
特徵,那麼,作爲文檔說:
結合Spliterator後應,盡最大努力的基礎上,如果檢測到結構的干擾扔ConcurrentModificationException
。這樣做的Spliterators被稱爲失效快速。
所以HashMap.keySet().spliterator()
不IMMUTABLE
(因爲這Set
可以修改),而不是CONCURRENT
(併發更新是不安全的HashMap
)。因此,它只是檢測到併發更改,並在spliterator文檔規定的情況下拋出ConcurrentModificationException
。
另外值得援引HashMap
文件:所有的此類的「collection視圖方法」返回
的迭代器都是快速失敗的:如果地圖隨時迭代後結構修飾除了通過迭代器自己的remove方法以外的任何方式創建,迭代器都會拋出ConcurrentModificationException
。因此,面對併發修改,迭代器快速而乾淨地失敗,而不是在將來未定的時間冒着任意的,非確定性的行爲冒險。
請注意,迭代器的故障快速行爲無法得到保證,因爲一般來說,在出現非同步併發修改時不可能做出任何硬性保證。失敗快速迭代器在盡力而爲的基礎上拋出ConcurrentModificationException
。因此,編寫一個依賴於此異常的程序是正確的:迭代器的故障快速行爲應僅用於檢測錯誤。
雖然它只說了迭代器,但我相信這對於分割器來說也是一樣的。
我認爲這是最好的答案,但您可以編輯它以添加@Eran提到的解決方案。對於將來有同樣問題的人來說,這將是100%滿意的。 – jaskmar
@MariuszJaskółka,伊蘭的答案也在這裏,其他人也可能會看到它。這是正確的,我贊成它。我可以添加對他的解決方案的參考。 –