2012-09-11 67 views
0

我在使用map和執行remove.How時出現下面的錯誤,如何避免這種情況?hashmap得到併發修改的問題異常

Caused by: java.util.ConcurrentModificationException 
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793) 
    at java.util.HashMap$EntryIterator.next(HashMap.java:834) 
    at java.util.HashMap$EntryIterator.next(HashMap.java:832) 


Map<FormField, Object> ItemMap = domainItem.getValues();   
    for (Map.Entry<FormField, Object> ValMap : ItemMap.entrySet()) {   
     List<Field> groupIdList = Mapper.getGroupId(groupFieldId);   
     for (Field field : groupIdList) { 
      ItemMap.put(new FormField(field), domainItem.getDomainItemLinkId()); 
     } 
     ItemMap.remove(ValMap.getKey()); 
    } 

回答

6

更新:

使用iterator和ConcurrentHashMap,以避免這種情況

繼不會拋出異常

Map<Integer, String> map = new ConcurrentHashMap<Integer, String>(); 
    map.put(1, "a"); 
    map.put(2, "b"); 
    map.put(3, "c"); 
    map.put(4, "d"); 
    for (Iterator<Integer> keys = map.keySet().iterator(); keys.hasNext();) { 
     Integer key = keys.next(); 
     String val = map.get(key); 
     map.remove(key); 
    } 

或使用其他地圖而迭代和結束時將其複製到源

例如:

Map<Integer, String> dummy = new HashMap<Integer, String>(); 
    map.put(1, "a"); 
    map.put(2, "b"); 
    map.put(3, "c"); 
    map.put(4, "d"); 
    dummy.putAll(map); 
    for (Iterator<Integer> keys = dummy.keySet().iterator(); keys.hasNext();) { 
     Integer key = keys.next(); 
     String val = map.get(key); 
     map.remove(key); 
    } 
    System.out.println(map); 
+0

如何避免這種情況我還需要添加數據。 – pars

+0

你能編輯上面的代碼片段並給我看 – pars

+0

,請解釋我如何在我的上面代碼片段中使用迭代器 – pars

0

甲地圖通過在鍵 - 值對的鍵進行排序。當您在遍歷Map時添加或刪除元素時,程序本質上會丟失它在Map中的「where」的軌跡。

要解決此問題,請嘗試製作單獨的臨時轉移地圖。還有一個名爲Iterator的課程可能適合您的需求。

+0

,請解釋我如何在上面的代碼段中使用迭代器 – pars

+0

Jigar Joshi在上面的答案中用代碼示例對它進行了解釋。 =) – asteri

0

避免此問題的一種方法是迭代副本。

for (Map.Entry<FormField, Object> ValMap : 
    new HashMap<FormField, Object>(ItemMap).entrySet()) { 
+0

如果我創建一個副本,然後我可以使用(字段字段:groupIdList)ItemMap.put(新的FormField(字段), domainItem.getDomainItemLinkId()); } ItemMap.remove(ValMap.getKey()); – pars

+0

從您提供的代碼中無法說出您的交互非常複雜。我會將這段代碼移動到'domainItem'類中,這樣你就可以看到所有的依賴關係。 –

+0

Map ItemMap = domainItem.getValues();對於(Map.Entry ValMap: new HashMap (ItemMap).entrySet()){ List groupIdList = Mapper.getGroupId(groupFieldId); (Field field:groupIdList){ ItemMap.put(new FormField(field),domainItem.getDomainItemLinkId()); } ItemMap.remove(ValMap。信息getKey()); } – pars

0

可以在沒有地圖的副本來完成,執行這個例子,看看代碼:

public static void main(String[] args) 
    { 

    System.out.println("creating map ..."); 

    Map<String, String> dummyMap = new HashMap<>(); 
    while (dummyMap.size() < 10) 
    { dummyMap.put(String.valueOf(new Random().nextInt()), String.valueOf(new Random().nextInt())); } 


    System.out.println("start, map size: " + dummyMap.size() + ", keys=" + dummyMap.keySet()); 


    System.out.print("going to remove: "); 
    for (Iterator<String> keys = dummyMap.keySet().iterator(); keys.hasNext();) 
    { 
     final String key = keys.next(); 

     // delete map entries per random 
     if(new Random().nextInt(3)>1) 
     { 
     System.out.print(key+" "); 
     keys.remove(); 
     } 
    } 
    System.out.print("\n"); 

    System.out.println("done, map size: " + dummyMap.size() + ", keys=" + dummyMap.keySet()); 
    } 

,並看看this similar question

HTH,