【发布时间】:2015-08-27 17:19:28
【问题描述】:
我正在尝试编写一个递归程序,它可以打印从文件中获取的整数列表的所有排列,我正在使用 HashMap 来存储列表,其中键是数字,值是键的次数出现在列表中。代码如下:
import java.util.*;
import java.io.*;
public class perm
{
public static void permute(HashMap<Integer, Integer> map)
{
if(map.isEmpty())
{
System.out.println();
}
else
{
Set<Integer> keys = map.keySet();
for(int num: keys)
{
System.out.print(Integer.toString(num)+",");
int val = map.get(num) -1;
if(val == 0)
{
map.remove(num);
}
else
{
map.put(num, val);
}
permute(map);
}
}
}
public static void main(String args []) throws FileNotFoundException
{
HashMap <Integer, Integer> map = new HashMap<Integer, Integer>();
Scanner in = new Scanner(new File(args[0]));
int num;
while(in.hasNextInt())
{
num = in.nextInt();
if(map.containsKey(num))
{
map.put(num, map.get(num)+1);
}
else
{
map.put(num,1);
}
}
permute(map);
}
}
我得到一个并发错误,但我不明白为什么,错误如下:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at perm.permute(perm.java:15)
at perm.permute(perm.java:27)
at perm.permute(perm.java:27)
at perm.permute(perm.java:27)
at perm.main(perm.java:48)
--------基于cmets编辑的代码--------------------
import java.util.*;
import java.io.*;
public class perm
{
public static void permute(HashMap<Integer, Integer> map)
{
if(map.isEmpty())
{
System.out.println();
}
else
{
Iterator it = map.entrySet().iterator();
//Set<Integer> keys = map.keySet();
while(it.hasNext())
//for(int num: keys)
{
Map.Entry pair = (Map.Entry)it.next();
int num = (int) pair.getKey();
System.out.print(Integer.toString(num)+",");
int val = (int) pair.getValue()-1;
//HashMap<Integer, Integer> newMap = map;
//int val = map.get(num) -1;
if(val == 0)
{
//newMap.remove(num);
it.remove();
}
else
{
//newMap.put(num, val);
pair.setValue(val);
}
permute(map);
}
}
}
public static void main(String args []) throws FileNotFoundException
{
HashMap <Integer, Integer> map = new HashMap<Integer, Integer>();
Scanner in = new Scanner(new File(args[0]));
int num;
while(in.hasNextInt())
{
num = in.nextInt();
if(map.containsKey(num))
{
map.put(num, map.get(num)+1);
}
else
{
map.put(num,1);
}
}
permute(map);
}
}
同样的错误仍然存在。然后我回到最初的方法并存储了我试图迭代的 HashMap 的临时副本,并且只修改了临时副本而不是原始副本,同样的错误仍然存在。
---- 基于答案 1 的代码编辑 ------
import java.util.*;
import java.io.*;
public class perm
{
public static void permute(HashMap<Integer, Integer> map)
{
if(map.isEmpty())
{
System.out.println();
}
else
{
//Iterator it = map.entrySet().iterator();
HashMap<Integer, Integer> newMap = map;
Set<Integer> keys = map.keySet();
//while(it.hasNext())
for(int num: keys)
{
//Map.Entry pair = (Map.Entry)it.next();
//int num = (int) pair.getKey();
System.out.print(Integer.toString(num)+",");
//int val = (int) pair.getValue()-1;
//HashMap<Integer, Integer> newMap = map;
int val = map.get(num) -1;
if(val == 0)
{
newMap.remove(num);
//it.remove();
}
else
{
newMap.put(num, val);
//pair.setValue(val);
}
permute(newMap);
}
}
}
public static void main(String args []) throws FileNotFoundException
{
HashMap <Integer, Integer> map = new HashMap<Integer, Integer>();
Scanner in = new Scanner(new File(args[0]));
int num;
while(in.hasNextInt())
{
num = in.nextInt();
if(map.containsKey(num))
{
map.put(num, map.get(num)+1);
}
else
{
map.put(num,1);
}
}
permute(map);
}
}
【问题讨论】:
-
我使用了上述线程中的建议,但仍然遇到同样的错误。
-
请发布您的更新代码。如果你正确使用了这个帖子的建议,你不会得到
ConcurrentModificationException。 -
在---Edit line---之后添加的代码---
-
remove()上的it声明很好。问题是对pair.setValue(...)的调用。在此表单中迭代此地图时,您无法将元素添加到地图。一般的方法是创建一个新的临时地图,并在迭代后合并这些地图。 -
对上次编辑的评论:
newMap和map是同一个对象。同样的问题也适用。您可以批量插入/删除并在完成迭代后应用它们吗?