数独解算器,线程中出现异常;“主要”;其迭代器上的java.util.ConcurrentModificationException
我得到以下错误:数独解算器,线程中出现异常;“主要”;其迭代器上的java.util.ConcurrentModificationException,java,hashset,concurrentmodification,Java,Hashset,Concurrentmodification,我得到以下错误: Exception in thread "main" java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810) at java.util.HashMap$KeyIterator.next(HashMap.java:845) at sudoku.Main.solve2(Ma
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810)
at java.util.HashMap$KeyIterator.next(HashMap.java:845)
at sudoku.Main.solve2(Main.java:143)
at sudoku.Main.next2(Main.java:168)
at sudoku.Main.solve2(Main.java:153)
at sudoku.Main.main(Main.java:284)
我不理解java.util.HashMap$KeyIterator.next
和java.util.HashMap$HashIterator.nextEntry
错误消息,因为我无法为HashSet
显式地获取密钥集,我假设迭代器在默认情况下正在遍历密钥集
我没有使用线程,只是递归调用。
这是怎么回事
static void solve2(int row, int col, int [][]grid, ArrayList<HashSet<Integer>> availableNumsInRows,
ArrayList<HashSet<Integer>> availableNumsInColumns){
if (row>=grid.length){
System.out.println("solution found");
printSolvedGrid(grid);
System.out.println("move count for this sudoku is " + moveCounter);
moveCounter=0; //reset counter
return;
}
if( grid[row][col] != 0 ){
next2( row, col, grid, availableNumsInRows, availableNumsInColumns ) ;
}
else {
// Find a valid number for the empty cell
Iterator <Integer> iterator = availableNumsInRows.get(row).iterator();
for( int num = iterator.next() ; iterator.hasNext(); num = iterator.next())
{
if( checkRow(row,num,grid) && checkCol(col,num,grid) && checkBox(row,col,num,grid) )
{
grid[row][col] = num ;
availableNumsInRows.get(row).remove(new Integer(num));
availableNumsInColumns.get(col).remove(new Integer(num));
moveCounter++;
//printSolvedGrid(grid);
next2( row, col, grid, availableNumsInRows, availableNumsInColumns );
}
}
grid[row][col] = 0 ;
}
}
//helper function for the first solution approach
public static void next2( int row, int col, int [][] grid , ArrayList<HashSet<Integer>> availableNumsInRows,
ArrayList<HashSet<Integer>> availableNumsInColumns )
{
if( col < 8 ) //pass to next col
solve2( row, col + 1, grid, availableNumsInRows, availableNumsInColumns) ;
else //pass to next row
solve2( row + 1, 0, grid, availableNumsInRows, availableNumsInColumns) ;
}
我仍然得到ConcurrentModificationException
,这是为什么
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810)
at java.util.HashMap$KeyIterator.next(HashMap.java:845)
at sudoku.Main.solve2(Main.java:148)
at sudoku.Main.next2(Main.java:175)
at sudoku.Main.solve2(Main.java:137)
at sudoku.Main.next2(Main.java:175)
at sudoku.Main.solve2(Main.java:159)
at sudoku.Main.next2(Main.java:175)
at sudoku.Main.solve2(Main.java:137)
at sudoku.Main.next2(Main.java:175)
at sudoku.Main.solve2(Main.java:159)
at sudoku.Main.next2(Main.java:175)
at sudoku.Main.solve2(Main.java:159)
at sudoku.Main.main(Main.java:291)
Java Result: 1
在遍历集合时,您需要通过调用其迭代器来修改集合,否则将发生
ConcurrentModificationException
:
...
availableNumsInRows.get(row).remove(new Integer(num));
availableNumsInColumns.get(col).remove(new Integer(num));
...
您正在对哈希映射进行迭代,但也在同一循环中修改它。这将导致这个例外 通过调用
iterator.remove()
而不是availableEnumsInRows.get(row.remove)(新整数(num)),可以在一次调用中避免这种情况代码>
但是,您正在递归,每次都创建一个新的迭代器。如果您通过嵌套调用中的一个迭代器删除了某些内容,那么当您在外部调用中进行迭代时,您将遇到同样的问题
一种选择是简化代码以避免以这种方式递归;另一种方法是使用单个迭代器并将其传递。当使用迭代器进行迭代时,不能从集合
(其中ArrayList
是其中的一部分)中删除项。您可以使用iterator.remove()
从迭代器中删除元素,而不是使用availableEnumsInRows.get(row).remove(new Integer(num))
您不应该向哈希集或哈希映射添加/删除项(顺便说一句,在迭代过程中,HashSet
的基类是哪个。这导致了异常
正如Jon Skeet所建议的那样,使用迭代器删除项目。您在对地图进行迭代时正在修改地图
而不是这个
availableNumsInRows.get(row).remove(new Integer(num));
试试这个
iterator.remove();
这可能就足够了。我尝试了这个mod,但仍然收到ConcurrentModificationException,请阅读我的编辑。我怀疑您的代码有点变化,但堆栈跟踪中的行号没有(810,845)。您确定要执行新代码吗?是的,行号(和错误标记数)也有变化在堆栈跟踪中,在前三条消息之后进行更改:-/
iterator.remove();