数独解算器,线程中出现异常;“主要”;其迭代器上的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();