首先你們先看一段代碼:java
for (Map<String, Object> map : dataMap) { String roomStateStr = (String) map.get("RoomState"); int mapRoomState = Integer.parseInt(roomStateStr); if(mapRoomState != roomStateID){ dataMap.remove(map); } }
現象:jvm
該程序會拋出一個 java.util.ConcurrentModificationException異常。spa
分析:code
對 Collection 或 Map 進行迭代操做過程當中嘗試直接修改 Collection / Map 的內容時,會拋出java.util.ConcurrentModificationException 異常。 由於在修改數據時不能同步原有list中數據,當下一次循環時找不到數據。orm
解決辦法:對象
Iterator 在工做的時候是不容許被迭代的對象被改變的,使用 Iterator 自己的方法 remove() 來刪除對
象, Iterator.remove() 方法會在刪除當前迭代對象的同時維護索引的一致性。索引
改後代碼:rem
Iterator<Map<String, Object>> ite = dataMap.iterator(); while (ite.hasNext()) { Map<String, Object> map = ite.next(); String roomStateStr = (String) map.get("RoomState"); int mapRoomState = Integer.parseInt(roomStateStr); if (mapRoomState != roomStateID) { ite.remove(); } }
補充:get
或許有人可能會問若是我不用加強for循環,直接用.get(index)方法會不會報錯?同步
代碼以下:
for (int i = 0; i < dataMap.size(); i++) { String roomStateStr = (String) dataMap.get(i).get("RoomState"); int mapRoomState = Integer.parseInt(roomStateStr); if (mapRoomState != roomStateID) { dataMap.remove(dataMap.get(i)); } }
你們能夠看到經過list的下表索引來修改list數據是不會出錯,可是不能徹底遍歷,會漏掉遍歷幾個數據,獲得的結果會比正確的結果多
分析:
你們能夠這樣認爲:經過所引來循環時,jvm記錄的是所引值,當移除當前對象後,其餘元素的索引號不會同步改變。下次循環仍能夠找到對應數據。而加強for循環,記錄的是當前對象,當下次循環時,會先找到該對象,而後遊標向下移,這時候找不到對象因此結果會混亂。