我想写这样的代码 -
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
}