Mp *_*ega 3 java iteration concurrency android map
我在下面有以下代码
Map<String, Integer> buyingItemEnumerationMap = this.toBuyItemEnumeration;
for (Entry<String, Integer> item : buyingItemEnumerationMap.entrySet()) {
if(RandomEngine.boolChance(50)){ //will delete?
buyingItemEnumerationMap.remove(item.getKey());
}
if(buyingItemEnumerationMap.size() == 1){
break;
}
}
Run Code Online (Sandbox Code Playgroud)
现在我正在使用Android游戏,上面的代码以多线程方式运行.现在我有一个例外java.util.ConcurrentModificationException.我已经研究过如何解决这个问题,但似乎没有对我有所帮助.我在上面的代码上做的是随机删除一个条目.我怎样才能在那里实现它?
除非使用,否则在迭代时不能从集合中删除元素Iterator.
这就是导致例外的原因.
buyingItemEnumerationMap.remove(item.getKey());
Run Code Online (Sandbox Code Playgroud)
使用Iterator #remove()删除元素,同时迭代你的集合
Iterator<Map.Entry<String, Integer>> iterator =
buyingItemEnumerationMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Integer> item = iterator.next();
if(RandomEngine.boolChance(50)){ //will delete?
iterator.remove();
}
//..
}
Run Code Online (Sandbox Code Playgroud)
编辑:(响应OP的评论)
是的,删除通过完成Iterator#remove()在Set由归国 HashMap.entrySet()在底层将反映Map的Set是它的支持.在这里引用JavaDoc:
返回此映射中包含的映射的Set视图.该集由地图支持,因此对地图的更改将反映在集中,反之亦然.
使用Iterator.
Iterator<Map.Entry<String, Integer>> iter = this.toBuyItemEnumeration;
while (iter.hasNext()) {
Map.Entry<String, Integer> entry = iter.next();
if (some-condition){
iter.remove();
}
}
Run Code Online (Sandbox Code Playgroud)
这个怎么运作 ?
javadoc ConcurrentModificationException说:
如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常.例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常.
该字段int expectedModCount被启动为等于字段protected transient int modCount = 0;(这对于集合和映射有效),并modCount跟踪对象的结构修改.如果modCount在迭代的某个时刻变得不相等expectedModCount,则ConcurrentModificationException抛出a.
通过使用Iterator对地图/集合进行结构更改(如删除元素),我们确保删除操作将正确执行,例如modCount将等于expectedModCount.
| 归档时间: |
|
| 查看次数: |
2620 次 |
| 最近记录: |