0

我收到以下错误:

     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.nextjava.util.HashMap$HashIterator.nextEntry错误消息,因为我无法HashSet明确地获取 keySet,我假设 Iterator 默认情况下正在通过 keySet。

我没有使用线程,只是递归调用。这里发生了什么?

 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) ;
   }

编辑:

我将代码更改为:

   while (iterator.hasNext())
             {

                num=iterator.next();

                if( checkRow(row,num,grid) && checkCol(col,num,grid) && checkBox(row,col,num,grid) )
                {
                   grid[row][col] = num ;

                   iterator.remove();

                   moveCounter++;


                   next2( row, col, 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
4

5 回答 5

1

您正在迭代哈希映射,但也在同一个循环中对其进行修改。这将导致这个异常。

您可以通过调用iterator.remove()不是availableNumsInRows.get(row).remove(new Integer(num));

但是,您是递归的,每次都创建一个新的迭代器。如果您通过嵌套调用中的一个迭代器删除某些内容,那么当您在外部调用中进行迭代时,您将遇到同样的问题。

一种选择是简化代码以避免以这种方式递归;另一种是使用单个迭代器并传递它。

于 2011-07-07T14:28:56.350 回答
1

您在迭代 Map 时正在修改它。

而不是这个

availableNumsInRows.get(row).remove(new Integer(num));

试试这个

iterator.remove();

可能就够了。

于 2011-07-07T14:30:27.923 回答
0

您需要在迭代时通过调用它的迭代器来修改集合,否则ConcurrentModificationException会发生:

...
availableNumsInRows.get(row).remove(new Integer(num));
availableNumsInColumns.get(col).remove(new Integer(num));
...
于 2011-07-07T14:27:50.803 回答
0

当您Collection使用. 您可以使用而不是从迭代器中删除元素。ArrayListIteratoriterator.remove()availableNumsInRows.get(row).remove(new Integer(num))

于 2011-07-07T14:29:03.310 回答
0

HashSet您不应该在或HashMap(顺便说一句是迭代期间的基类)中添加/删除项目HashSet。这会导致异常。

正如 Jon Skeet 建议的那样,使用迭代器来删除项目。

于 2011-07-07T14:29:04.617 回答