我在使用 HashMap 时抛出 java.util.ConcurrentModificationException
Posted
技术标签:
【中文标题】我在使用 HashMap 时抛出 java.util.ConcurrentModificationException【英文标题】:I am getting java.util.ConcurrentModificationException thrown while using HashMap 【发布时间】:2012-07-28 05:15:19 【问题描述】:与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】:或者,如果inScopeActiveRegionIdSet
的大小更小,那么迭代它可能会更短更快:
for (BigDecimal bigDecimal : inScopeActiveRegionIdSet)
transactionLogMap.remove(bigDecimal);
【讨论】:
【参考方案2】:问题出在这几行
for (BigDecimal bigDecimal : transactionLogMap.keySet())
if(!inScopeActiveRegionIdSet.contains(bigDecimal))
transactionLogMap.remove(bigDecimal);
当您调用transactionLogMap.remove
时,您正在遍历transactionLogMap
,同时还直接修改底层Collection
,这是不允许的,因为增强的for 循环无法看到这些更改。
正确的解决方法是使用Iterator
:
Iterator<BigDecimal> it = transactionLogMap.keySet().iterator();//changed for syntax correctness
while (it.hasNext())
BigDecimal bigDecimal = it.next();
if(!inScopeActiveRegionIdSet.contains(bigDecimal))
it.remove();
【讨论】:
【参考方案3】:根据 javadoc
ConcurrentModificationException 可能会被检测到对象的并发修改的方法抛出,而这种修改是不允许的
transactionLogMap.remove(bigDecimal);
使用Iterator
代替for loop
并在迭代器上调用remove。
例子:
Iterator iter = transactionLogMap.keySet().iterator();
while(iter.hasNext())
iter.remove();
或
您可以考虑使用ConcurrentHashMap
注意:输入代码,作为参考。可能存在语法错误。
【讨论】:
【参考方案4】:在迭代集合时,您不能从集合中删除项目。这会导致您遇到异常。
当你打电话时:
for(TypeX x: collectionOfX) ...
幕后发生的事情是,您正在为 collectionOfX 创建一个迭代器,并进行迭代,直到您明确地从循环中中断或迭代器的 hasNext() 为 false。
如果您需要在迭代期间从集合中删除项目,则需要将 foreach
构造替换为对迭代器的显式调用。比如:
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.
【讨论】:
以上是关于我在使用 HashMap 时抛出 java.util.ConcurrentModificationException的主要内容,如果未能解决你的问题,请参考以下文章
我在 Flutter 中遇到了一个问题:在构建 TextField 时抛出了以下断言,它使我遇到了一个奇怪的问题
“未处理的异常:NoSuchMethodError:在 null 上调用了 getter 'iterator'。”当我在颤振中使用 google_maps_polyline 插件时抛出
Scrapy 使用 crawlerprocess 运行时抛出错误