我试图让removeItemFromMapByValue
方法与removeItemFromMapByValue
一起工作,但是当我开始编译代码时,我得到 ConcurrentModificationException 。 removeItemFromMapByValue
必须删除值中的相同名称。
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
答案 0 :(得分:3)
<强>这里:强>
for (Map.Entry<String, String> pair : map.entrySet()){
String name = pair.getValue();
removeItemFromMapByValue(map, name); //you are about to delete a map item here!
}
您正在修改您当前循环的集合==&gt; ConcurrentModificationException
答案 1 :(得分:3)
简单的解决方案是修复第一种方法,因为这样可以避免错误并且行为正确。
// 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();
}
此解决方案的问题是从嵌套中调用它,它将删除所有匹配条目,就像在代码中一样。即它将删除所有条目。