Java根據條件刪除Map中元素

今天在寫程序過程當中,須要根據判斷條件刪除一個Map中的相應數據,我天然而然想到能夠經過調用Map中的remove(Object key)函數進行刪除:代碼以下:java

public Map<Double, Double> processMap(Map<Double, Double> list) {算法

Map<Double, Double> map = list;數據結構

Iterator<Double> iter = map.keyset().iterator;多線程

while(iter.hasNext()) {函數

double key = iter.next();測試

if (key > 5).net

map.remove(key);線程

}指針

return map;對象

}

可是運行程序的時候卻沒有正常刪除元素,而是提示Java.util.ConcurrentModificationException」錯誤,非常疑惑,於

是找了一些關於Map的資料發現:Map的實現不是同步的。若是程序中出現多個線程同時訪問一個Map,而其中至少一個線程修改Map

時,它必須保持外部同步。而經過查看Iterator原理髮現,Iterator是工做在一個獨立的線程中,而且擁有一個 mutex鎖,就是說

Iterator在工做的時候,是不容許被迭代的對象被改變的,因此調用Iterator操做得到的對象在多線程修改Map的時候會自動失效。

Iterator被建立的時候,創建了一個內存索引表(單鏈表),這 個索引表指向原來的對象,當原來的對象數量改變的時候,這個索

引表的內容沒有同步改變,因此當索引指針往下移動的時候,便找不到要迭代的對象,因而產生錯 誤。Map、List、Set等是動態

的,可變對象數量的數據結構,可是Iterator則是單向不可變,只能順序讀取,不能逆序操做的數據結構,當 Iterator指向的原始

數據發生變化時,Iterator本身就迷失了方向。

既然找到了問題的緣由,那麼如何解決呢?能夠經過調用Iterator的remove(Object o)函數來移除元素。

測試代碼以下:

 

public Map<Double, Double> processMap(Map<Double, Double> list) {

Map<Double, Double> map = list;

Iterator<Double> iter = map.keyset().iterator;

while(iter.hasNext()) {

double key = iter.next();

if (key > 5) {

//   map.remove(key);  // java.util.ConcurrentModificationException

iter.remove(key);  // OK

}

}

return map;

}

 

同時,在遍歷Map過程當中,調用put(key, value)函數來添加元素,也會出現一樣的問題,因此一樣須要使用迭代器的相應函數來添加。

相關文章
相關標籤/搜索