我想写这样的代码 -
for (Map.Entry<Long, Integer> e : map.entrySet()){
map.remove(k);
map.put(x, value);
}
但我得到了java.util.ConcurrentModificationException
我也尝试使用Iterator
但我得到了相同的Exception
解释为什么会导致ConcurrentModificationException
map.remove(k);
map.put(x, value);
for-each 循环还在内部创建 of 的迭代entrySet
器map
。在遍历 map 时,您通过将值再次放入 map( map.put(x,value)
) 修改了 map 的结构,这导致了这种情况ConcurrentModificationException
。
它甚至在文档中得到了很好的解释-
所有此类的“集合视图方法”返回的迭代器都是快速失败的:如果在创建迭代器后的任何时间对映射进行结构修改,除了通过迭代器自己的 remove 方法之外,迭代器将抛出 ConcurrentModificationException . 因此,面对并发修改,迭代器快速而干净地失败,而不是在未来不确定的时间冒任意的、非确定性的行为。
如何解决这个-
您必须在迭代时更改此地图的结构,您可以稍后插入此值,例如保留一个临时地图并在迭代完成后将其添加到主地图中。
Map<Long, Integer> tempMap = new HashMap<>();
for (Map.Entry<Long, Integer> e : map.entrySet()){
map.remove(k);
tempMap.put(x, value);
}
map.putAll(tempMap);
迭代一个副本,你可以添加/删除就好了:
for (Map.Entry<Long, Integer> e : new LinkedHashMap<Long, Integer>(map).entrySet()){
map.remove(k);
map.put(x, value);
}
它甚至不再是代码行,因为复制 ims 是通过复制构造函数内联生成的。LinkedHashMap
选择保留迭代顺序(如果重要的话)。
下面给出了从地图中删除元素的示例代码片段。
for(Iterator<Map.Entry<Long, Integer>> it = map.entrySet().iterator();it.next();)
{
Map.Entry<String, String> entry = it.next();
if(//some logic)
it.remove();
}
如果您的代码涉及大量添加和删除,您可能只想使用 ConcurrentHashMap。并发哈希映射
You will have to create a copy of your map using copy constructor. Now iterate on 1 and modify second map. I am assuming that you will not need to iterate newly added value as it wont make much sense.
You can achieve your task by creating a copy is because the keys will remain same in both.
EDIT:
I dont think its a good idea to iterate the newly added element to a Hashmap. If you check the api's provided by Iterator then you will find only remove method, there is no add method in it. There is a reason behind this and you can check javadoc for this. Now coming to the point, on how to iterate newly added element.
HashMap
. So you will iterate one and modify the the other Map
.Map
, i would like to use ListIterator
for this [this is different from normal Iterator
].keyset
of Map1 and convert it to a list using ArrayList(Collection<? extends E> c)
.ListIterator
from List
created in step 3, and add, remove elements in ListIterator
as well as in Map2 [Remeber you need to add , remove both in ListIterator
and Map2]. 因为你不能那样做。
一个简单的解决方案是使用另一个临时映射,在其中放置所需的值,最后用原始映射切换指针(即 Map = newMap )
尝试按如下方式浏览地图
while (tree_map.size() > 0){
// if k is key
if (tree_map.containsKey()){
tree_map.remove(k);
}
tree_map.put(x, value);
break;
// can go through the for loop or other code as per requirements
}