我有以下结构:
public class Object1{
private HashMap<Double, Node> myMap;
...
public void cancelItem(Item o) {
for(Map.Entry<Double, Node> nn: myMap.entrySet()) {
if(nn.getValue().containItem(o)) {
nn.getValue().cancelItemFromNode(o);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
和另一堂课
public class Node{
private HashMap<String,Item> itemIDHashMap;
public boolean containItemID(Item o) {
return itemIDHashMap.containsKey(o.getItemID());
}
public void cancelItemFromNode(Item o) {
if(itemIDHashMap.containsKey(o.getItemID())) {
itemIDHashMap.remove(o.getItemID());
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以,上面的代码做到这一点:无论何时Object1的cancelItem方法被调用时,它遍历的myMapHashMap来找到一个Node,它包含了另一个HashMap中itemIDHashMap,并检查是否itemIDHashMap包含相同的项目ID,如果确实如此,那么从删除的项itemIDHashMap.
现在,从我的理解,因为我在myMap不使用迭代器的情况下迭代hashmap 而我试图从hashmap中删除元素,为什么它不会ConcurrentModificationException在运行时抛出?
更新:
道歉.我忘了澄清.我知道我实际上迭代一个散列图,但从另一个散列图中删除键值对.但是,在我上面的设计中,我相信我仍在修改内容Node,它仍然是myMaphashmap的一部分,因为我Item从Node类的hashmap中删除了键值对.从技术上讲,我还在修改myMaphashmap 的内容?
您正在迭代一个条目集Map- myMap- 但是从不同的Maps - 中删除条目itemIDHashMap.因此没有理由ConcurrentModificationException被抛出.
从a的itemIDHashMap实例变量中删除条目Node,这是Map您正在迭代的值,不会对其进行任何结构更改,Map因此是允许的.
以下是来自HashMapJavadoc的一些相关引用,它解释了在ConcurrentModificationException迭代以下条目时抛出的时间Map:
结构修改是添加或删除一个或多个映射的任何操作; 仅更改与实例已包含的键关联的值不是结构修改.
...
所有这个类的"集合视图方法"返回的迭代器都是快速失败的:如果在创建迭代器之后的任何时候对映射进行结构修改,除了通过迭代器自己的remove方法之外,迭代器将抛出ConcurrentModificationException..因此,在并发修改的情况下,迭代器快速而干净地失败,而不是在未来的未确定时间冒任意,非确定性行为的风险.
entrySet() 是上面提到的"集合视图方法"之一.
| 归档时间: |
|
| 查看次数: |
57 次 |
| 最近记录: |