java - 编译报错ConcurrentModificationException,试图使用移除同名的方法

标签 java hashmap static-methods

我试图让我的 removeItemFromMapByValue 方法与 removeItemFromMapByValue 一起工作,但是当我开始编译我的代码时,我得到了 ConcurrentModificationExceptionremoveItemFromMapByValue 必须删除值中的相同名称。

    public class Solution
        {
            public static HashMap<String, String> createMap()
            {
                HashMap<String, String> map = new HashMap<String, String>();
                map.put("Stallone", "Silvest");
                map.put("Morikone", "Enio");
                map.put("Vivaldi","Antonio");
                map.put("Belucci", "Monica");
                map.put("Gudini", "Harry");
                map.put("Verdo", "Dhuzeppe");
                map.put("Maracci", "Bruno");
                map.put("Carleone", "Vito");
                map.put("Bracco", "Luka");
                map.put("Stradivari", "Antonio");
                return map;
            }
            public static void removeTheFirstNameDuplicates(HashMap<String, String> map)
            {
                for (Map.Entry<String, String> pair : map.entrySet()){
                    String name = pair.getValue();
                    removeItemFromMapByValue(map, name);
                }
            }
            public static void removeItemFromMapByValue(HashMap<String, String> map, String value)
            {
                HashMap<String, String> copy = new HashMap<String, String>(map);
                for (Map.Entry<String, String> pair: copy.entrySet())
                {
                    if (pair.getValue().equals(value))
                        map.remove(pair.getKey());
                }
            }
            public static void main(String[] args)
            {
                HashMap<String, String> map = createMap();
                removeTheFirstNameDuplicates(map);
                System.out.println(map);
            }
        }

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:926)
    at java.util.HashMap$EntryIterator.next(HashMap.java:966)
    at java.util.HashMap$EntryIterator.next(HashMap.java:964)
    at com.javarush.test.level08.lesson08.task05.Solution.removeTheFirstNameDuplicates(Solution.java:32)
    at com.javarush.test.level08.lesson08.task05.Solution.main(Solution.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)

Process finished with exit code 1

最佳答案

简单的解决方案是修复第一种方法,因为这将避免错误并正确运行。

// remove any duplicated values, leaving one entry.
public static void removeTheFirstNameDuplicates(HashMap<String, String> map) {
     Map<K,V> map2 = invert(invert(map));
     map.clear();
     map.putAll(map2);
}

public static <K, V> Map<V, K> invert(Map<K, V> map) {
     Map<V, K> map2 = new HashMap<>();
     for(Map.Entry<K< V> entry: map.entrySet())
         map2.put(entry.getValue(), entry.getKey());
     return map2;
}

您的编译器不会产生 ConcurrentModifcationException。您应该查看堆栈轨道中的行以查看在迭代集合时在哪里修改集合,例如

for (Map.Entry<String, String> pair: copy.entrySet())
{
    if (pair.getValue().equals(value))
        map.remove(pair.getKey());
}

在这种情况下,您将在迭代时删除一个条目。一个简单的解决方案是直接使用 Iterator。通常您的 IDE 可以执行此重构。

for (Iterator<String> iter = copy.values().iterator(); iter.hasNext();) {
    if (iter.next().equals(value))
        iter.remove();
}

此解决方案的问题在于它是从嵌套调用的,它会删除所有匹配的条目,就像它在您的代码中所做的那样。即它将删除所有条目。

关于java - 编译报错ConcurrentModificationException,试图使用移除同名的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21952648/

相关文章:

java - FileInputStream/FileOutputStream 阻塞?

c++ - std::map 的底层结构是什么?

java - 使用 Java 的 HashMap 的键和值等于另外两个 HashMap 的值

floating-point - 如何找到 3D 矢量的哈希值?

c# - 我应该为 DataAccess 常用运算符使用静态方法吗?

java - 如何将方法调用到我的主方法中以便它可以执行程序?

java - 使用 SwingWorker 高效发布

java - 所有 fragment 都在 Activity 时加载

java - 在字符串数组中查找最大整数的最佳方法?

java - 为什么我可以在不实例化类的情况下调用类的方法?