问题描述:在做找出数组中出现次数大于数组长度 N/K 的数 这个题目中的遍历修改hashmap中的键值映射时(要求:value = 1,则清空该键值对;否则,value - 1)抛出异常如下:
Exception in thread "main"java.util.ConcurrentModificationExceptionat
java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)
at java.util.HashMap$EntryIterator.next(HashMap.java:1479)
at java.util.HashMap$EntryIterator.next(HashMap.java:1477)
出现原因:
Iterator做遍历的时候,HashMap被修改(bb.remove(ele), size-1),Iterator(Object ele=it.next())会检查HashMap的size,size发生变化,抛出错误ConcurrentModificationException。
解决方案:
1.使用“ConcurrentHashMap”替换HashMap,ConcurrentHashMap会自己检查修改操作,对其加锁,也可针对插入操作。
import java.util.concurrent.*;
import java.util.concurrent.ConcurrentHashMap;
// ConcurrentHashMap替换HashMap
ConcurrentHashMap<Integer, Integer> cands = new ConcurrentHashMap<>();
2.先记录要删除的键,然后删除。
public static void allCandsDeleteOne(HashMap<Integer, Integer> cands) {
List<Integer> removeList = new ArrayList<>();
for (Map.Entry<Integer, Integer> map : cands.entrySet()) {
// 遍历 k - 1 个候选人
int key = map.getKey();
int value = map.getValue();
if (value == 1) {
removeList.add(key);
}
cands.put(key, value - 1);
}
for (Integer removeKey : removeList) {
cands.remove(removeKey);
}
}