[英]How to remove multiple mappings in hashmap without ConcurrentModificationException?
I have 2 hashmaps: HashMap<String, Word> hmSmall, hmBig
. 我有2个哈希图:
HashMap<String, Word> hmSmall, hmBig
。 The mapping in each is many-to-one . 每个中的映射都是多对一的 。 Hence based on some criteria, I have to remove all the mappings corresponding to a particular value in both hashmaps.
因此,基于某些标准,我必须删除两个哈希图中对应于特定值的所有映射。 And for that, I am following this answer.
为此,我正在关注这个答案。
The problem is that I still get ConcurrentModificationException
while iterating over the hashmap. 问题是,在哈希表上进行迭代时,我仍然会收到
ConcurrentModificationException
。
Here is the code: 这是代码:
for (Iterator<Word> it = hmSmall.values().iterator(); it.hasNext(); i++) {
Word value = it.next();//java.util.ConcurrentModificationException here
String key = value.getKey();
if (hmBig.containsKey(key)) {
// if big contains less then remove from big
// else it.remove
if (hmBig.get(key).getTotalOccurances() < value
.getTotalOccurances()) {
hmBig.values().removeAll(
Collections.singleton(hmBig.get(key)));
} else {
// it.remove(); not using this based on https://stackoverflow.com/a/30214164/848377
hmSmall.values().removeAll(Collections.singleton(value));
}
}
}
Is there simple way out? 有简单的出路吗?
Iterator.remove()
必须通过Iterator.remove()
删除,以避免ConcurrentModificationException
。
Your Problem is, that, while you iterate through your HashMap with the Iterator Class, you are changing the size of the HashMap by removing elements... 您的问题是,当您使用Iterator类遍历HashMap时,您正在通过删除元素来更改HashMap的大小...
You can store the objects to be removed in a separate set and then remove all after the loop. 您可以将要删除的对象存储在单独的集中,然后在循环之后删除所有对象。
Compare the example from this stackoverflow post : 比较下面这个stackoverflow帖子中的示例:
Map<String, String> map = new HashMap<>();
map.put("a", "");
map.put("b", "");
map.put("c", "");
Set<String> set = new HashSet<> ();
set.add("a");
set.add("b");
map.keySet().removeAll(set);
System.out.println(map); //only contains "c"
Just put the removeAll call outside the loop: 只需将removeAll调用放在循环外即可:
public static void main(String[] args) {
// The test map
final Map<String, String> map = new HashMap<String, String>();
map.put("Key1", "Value");
map.put("Key2", "Value");
map.put("Key3", "Value");
.
// Print the map to confirm it worked.
for(final String key : map.keySet()) {
map.values().removeAll(Collections.singleton("Value"));
System.out.println(key + " = " + map.get(key));
}
}
the previous will cause exception ( ConcurrentModificationException ) try this: 前一个会导致异常( ConcurrentModificationException ),请尝试以下操作:
public static void main(String[] args) {
// The test map
final Map<String, String> map = new HashMap<String, String>();
map.put("Key1", "Value");
map.put("Key2", "Value");
map.put("Key3", "Value");
map.values().removeAll(Collections.singleton("Value"));
for(final String key : map.keySet()) {
System.out.println(key + " = " + map.get(key));
}
}
Now it works fine 现在工作正常
As @Ejp suggested , Iterator#remove()
is the optimal solution to get rid of ConcurrentModificationException
. 正如@Ejp所建议的那样,
Iterator#remove()
是摆脱ConcurrentModificationException
的最佳解决方案。
A similar kind of post here Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop . 此处类似的帖子遍历Collection,避免在循环中删除时避免ConcurrentModificationException 。
Also with java8 , you can very well use removeIf()
method . 同样在java8中,您可以很好地使用
removeIf()
方法。 Have a look at Iterating through a Collection, avoiding ConcurrentModificationException when removing in loop 看一遍遍Collection,避免在循环中删除时避免ConcurrentModificationException
So the key point here is not to change the size of the hashmap while iterating. 因此,此处的重点是不要在迭代时更改哈希图的大小。 Thus instead of deleting the entry within the loop, I added the key in an arraylist.
因此,我没有在循环中删除条目,而是在数组列表中添加了键。 And when the loop got over, I traversed through that arraylist and deleted the entries of the hashmap corresponding to the key in the arraylist.
当循环结束时,我遍历了该数组列表并删除了与该数组列表中的键相对应的哈希映射的条目。
Here is the code: 这是代码:
ArrayList<String> alsmallhm=new ArrayList<String>();
for (Iterator<Word> it = hmSmall.values().iterator(); it.hasNext(); i++) {
Word value = it.next();//java.util.ConcurrentModificationException here
String key = value.getKey();
if (hmBig.containsKey(key)) {
// if big contains less then remove from big
// else it.remove
if (hmBig.get(key).getTotalOccurances() < value
.getTotalOccurances()) {
hmBig.values().removeAll(
Collections.singleton(hmBig.get(key)));
} else {
// it.remove();
alsmallhm.add(key);
/*hmSmall.values().removeAll(Collections.singleton(value));*/
}
}
}
for(String s:alsmallhm){
hmSmall.values().removeAll(Collections.singleton(hmSmall.get(s)));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.