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

編集:

コードを次のように変更しました。

   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

ハッシュマップを繰り返し処理していますが、同じループで変更しています。それはまさにこの例外を引き起こします。

の代わりに呼び出すことで、 1 回の呼び出しでこれを回避できます。iterator.remove()availableNumsInRows.get(row).remove(new Integer(num));

ただし、毎回新しいイテレータを作成して再帰しています。ネストされた呼び出しのイテレータの 1 つを介して何かを削除すると、外側の呼び出しで反復するときに同じ問題が発生します。

1 つのオプションは、この方法での再帰を避けるためにコードを単純化することです。もう 1 つは、単一の反復子を使用してそれを渡すことです。

于 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

HashSetorに/から項目を追加/削除しないでくださいHashMap(ところで、HashSet反復中の基本クラスです。それが例外の原因です。

Jon Skeetが提案したように、代わりにイテレータを使用してアイテムを削除してください。

于 2011-07-07T14:29:04.617 に答える