值对Hashmap.while迭代该映射我在我没有得到Exception时插入另外1个键值对。当并发修改异常时,任何人都可以帮助我。
mycode的:
public static void main(String[] args) {
Map<String, String> hMap = new HashMap<String, String>();
hMap.put("FIRST", "1");
hMap.put("SECOND", "2");
hMap.put("THIRD", "3");
hMap.put("FOURTH", "4");
hMap.put("FIFTH", "5");
hMap.put("SIXTH", "6");
System.out.println("HashMap before iteration : " + hMap);
Iterator<String> hashMapIterator = hMap.keySet().iterator();
while (hashMapIterator.hasNext()) {
String key = hashMapIterator.next();
if (key.equals("FOURTH")) {
System.out.println("key = " + key);
hMap.put("sfsfsfsf2", "dsgfdsg");
}
}
System.out.println("HashMap after iteration : " + hMap);
}
答案 0 :(得分:0)
ConcurrentModificationException
的出现是因为Iterator
和Map#put
都可以同时修改Map
。为规避这一点,请为#put
操作创建临时存储空间:
Map<String, String> tmp = new HashMap<String, String>();
//...
Iterator<String> iter = hMap.keySet().iterator();
while(iter.hasNext()) {
//...
tmp.put("asdfasdf", "aasdfasdfas");
}
for (Entry<String, String> ops : tmp.entrySet())
hMap.put(ops.getKey(), ops.getValue());
一个简单的观察:如果#put
在迭代时添加一个新键,迭代器应该如何知道它必须在其新的迭代序列中“跳回”以获得新添加的键?
我的猜测是ConcurrentModificationException
可能不会发生key
来自#put
的{{1}}以使其位置(在entrySet
)之后当前迭代的元素,以便“旧”Iterator
仍然与“新”Iterator
一致,因为它已经交付“新”entrySet
具有相同顺序的元素。但这只是我猜测为什么它可能不会发生。这样的编码非常糟糕,因为现有代码将取决于Iterator
- hashCode
的{{1}}的实现细节。
key
的{{3}}跟踪HashMap
的结构修改:
此HashMap经过结构修改的次数结构修改是指更改HashMap中映射数量或以其他方式修改其内部结构(例如,重新散列)的修改。此字段用于在HashMap的Collection-views上快速生成迭代器。 (请参阅ConcurrentModificationException)。
当请求Map
前进时,检查HashIterator
自创建以来是否已更改。如果有,则抛出modCount
。这意味着如果您只更改与键关联的值,但不以任何方式更改键,则不会抛出它。
答案 1 :(得分:0)
您可能获得ConcurentModificationException
,但没有保证。密钥集的Map
(和HashMap
)contract为:
如果在对集合进行迭代时修改了地图 (除非通过迭代器自己的删除操作),的结果 迭代未定义。
某些实施尝试快速失败,但同样没有保证。 Hashmap
javadoc甚至说:
请注意,无法保证迭代器的快速失败行为 一般来说,不可能做出任何硬性保证 存在不同步的并发修改。快速失败 迭代器抛出ConcurrentModificationException就是尽力而为 基础。因此,编写一个依赖的程序是错误的 关于这个例外的正确性