Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HashMap中的并发修改异常_Java_List_Hashmap - Fatal编程技术网

Java HashMap中的并发修改异常

Java HashMap中的并发修改异常,java,list,hashmap,Java,List,Hashmap,我用Java编写这个程序,得到了一个Java.util.ConcurrentModificationException。代码摘录如下,如果需要更多代码,请告诉我 for (String eachChar : charsDict.keySet()) { if (charsDict.get(eachChar) < 2) { charsDict.remove(eachChar); } } 请帮助我:)在使用迭代器时,不允许从映射中删除元素 克服这一问题的典型解决

我用Java编写这个程序,得到了一个Java.util.ConcurrentModificationException。代码摘录如下,如果需要更多代码,请告诉我

for (String eachChar : charsDict.keySet()) {
    if (charsDict.get(eachChar) < 2) {
        charsDict.remove(eachChar);
    }
}

请帮助我:)

在使用迭代器时,不允许从映射中删除元素

克服这一问题的典型解决方案是:

List<String> toBeDeleted = new ArrayList<String>();
for (String eachChar : charsDict.keySet()) {
    if (charsDict.get(eachChar) < 2) {
        toBeDeleted.add(eachChar);
    }
}

for (String eachChar : toBeDeleted) {
    charsDict.remove(eachChar);
}
List toBeDeleted=new ArrayList();
for(字符串eachChar:charsDict.keySet()){
if(charsDict.get(eachChar)<2){
待删除。添加(每个字符);
}
}
for(字符串eachChar:toBeDeleted){
charsDict.移除(每个Char);
}

如果在线程之间切换,则使用ConcurrentHashMap可能是更好的选择。。。迭代器不是线程安全的,您应该创建一个新的迭代器,而不是在线程之间使用相同的迭代器。

您需要使用迭代器的
remove
方法:

for (Iterator<String> it = charsDict.keySet().iterator(); it.hasNext();) {
    String eachChar = it.next();
    if (charsDict.get(eachChar) < 2) {
        it.remove();
    }
}
最后看来,键实际上没有被使用,因此循环变成:

for (Iterator<Integer> it = charsDict.values().iterator(); it.hasNext();) {
    if (it.next() < 2) {
        it.remove();
    }
}
for(Iterator it=charsDict.values().Iterator();it.hasNext();){
if(it.next()<2){
it.remove();
}
}

另请参见。

这不是很有效。@assylia是正确的,但通常并不重要。不过,我更喜欢你的答案。接受这一点,因为代码更简洁。谢谢:)此外,我还了解了迭代器的使用过程。但是,我必须补充一点,Heuster的代码也可以很好地工作。@pratnala是的,另一个答案也可以-但是使用迭代器可以避免创建不必要的列表和两次查询映射(get+remove)。哇!只需迭代这些值并删除该值。但值不与键关联吗?那有什么不同呢?除了代码更干净这一事实之外,@pratnala在第三个示例中,
it.remove()
将有效地删除值和相关键。
for (Iterator<Map.Entry<String, Integer>> it = charsDict.entrySet().iterator(); it.hasNext();) {
    Map.Entry<String, Integer> e = it.next();
    String eachChar = e.getKey();
    int value = e.getValue();
    if (value < 2) {
        it.remove();
    }
}
for (Iterator<Integer> it = charsDict.values().iterator(); it.hasNext();) {
    if (it.next() < 2) {
        it.remove();
    }
}