我在使用HashMap时抛出了java.util.ConcurrentModificationException

ash*_*thi 0 java collections hashmap hashset

如何删除下面代码中的键值对与HashMap中的元素进行比较?

Map<BigDecimal, TransactionLogDTO> transactionLogMap = new HashMap<BigDecimal, TransactionLogDTO>();
for (BigDecimal regionID : regionIdList) {// Generation new logDTO
                                            // objects for each in scope
                                            // region
    transactionLogMap.put(regionID, new TransactionLogDTO());
}
Set<BigDecimal> inScopeActiveRegionIdSet = new HashSet<BigDecimal>();

for (PersonDTO personDTO4 : activePersons) {

    inScopeActiveRegionIdSet.add(personDTO4.getRegion());

}

for (BigDecimal bigDecimal : transactionLogMap.keySet()) {
    if (!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        transactionLogMap.remove(bigDecimal);
    }
}
Run Code Online (Sandbox Code Playgroud)

kos*_*osa 8

按照javadoc

当不允许这样的修改时,检测到并发修改对象的方法可能抛出ConcurrentModificationException

 transactionLogMap.remove(bigDecimal);
Run Code Online (Sandbox Code Playgroud)

而不是在迭代器上for loop使用Iterator和调用remove.

例:

Iterator iter = transactionLogMap.keySet().iterator();
while(iter.hasNext())
{
iter.remove();
}
Run Code Online (Sandbox Code Playgroud)

要么

您可以考虑使用ConcurrentHashMap

注意:键入代码,用作参考.可能存在语法错误.


fom*_*mil 6

问题出在这几行

for (BigDecimal bigDecimal : transactionLogMap.keySet()) {
    if(!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        transactionLogMap.remove(bigDecimal);
    }
}
Run Code Online (Sandbox Code Playgroud)

当您调用 时,您会迭代transactionLogMapwhile 并直接修改底层,这是不允许的,因为增强的 for 循环无法看到这些更改。CollectiontransactionLogMap.remove

正确的解决方案是使用Iterator

Iterator<BigDecimal> it = transactionLogMap.keySet().iterator();//changed for syntax correctness
while (it.hasNext()) {
    BigDecimal bigDecimal = it.next();
    if(!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        it.remove();
    }
}
Run Code Online (Sandbox Code Playgroud)