I am getting java.util.ConcurrentModificationException thrown while using HashMap

感情迁移 提交于 2019-12-12 01:03:23

问题


How do i remove the key value pair in the code below comparing with elements in 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);
    }
}

回答1:


The problem is in these lines

for (BigDecimal bigDecimal : transactionLogMap.keySet()) {
    if(!inScopeActiveRegionIdSet.contains(bigDecimal)) {
        transactionLogMap.remove(bigDecimal);
    }
}

You are iterating through the transactionLogMap whilst also directly modifying the underlying Collection when you call transactionLogMap.remove, which is not allowed because the enhanced for loop cannot see those changes.

The correct solution is to use the Iterator:

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



回答2:


As per javadoc

ConcurrentModificationException may be thrown by methods that have detected concurrent modification of an object when such modification is not permissible

 transactionLogMap.remove(bigDecimal);

Instead of for loop use Iterator and call remove on iterator.

Example:

Iterator iter = transactionLogMap.keySet().iterator();
while(iter.hasNext())
{
iter.remove();
}

OR

You may consider using ConcurrentHashMap

Note: Typed in code, use as reference. There may be syntax errors.




回答3:


You cannot remove items from a collection while you are iterating over it. This causes the exception you're getting.

When you call:

for(TypeX x: collectionOfX){ ... }

What happens under the hood is that you're creating an iterator for collectionOfX, and iterating until you explicitly break from the cycle or hasNext() for the iterator is false.

If you need to remove items from the collection during the iteration, you need to replace that foreach construct with an explicit call to the Iterator. Something like:

Iterator<BigDecimal> iter = transactionLogMap.keySet().iterator();
while(iter.hasNext()) {
   BigDecimal bDecimal = iter.next();
   ...
   iter.remove(); //this will remove the current item from the collection, without raising an exception.
}



回答4:


Alternatively, if inScopeActiveRegionIdSet is smaller in size, it might be shorter and faster to iterate it instead:

for (BigDecimal bigDecimal : inScopeActiveRegionIdSet) {
    transactionLogMap.remove(bigDecimal);
}


来源:https://stackoverflow.com/questions/11723159/i-am-getting-java-util-concurrentmodificationexception-thrown-while-using-hashma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!