1

私はこのコードを持っています:

アウトレットは、メソッドに渡される ArrayList です。riverBasin は int (int[][] riverBasin) の 2D "行列" です。

for (int[] item: outlets) {
    if (item[0] < 2 || item[0] > this.riverBasin.length - 1 || item[1] < 2 || item[1] > this.riverBasin[0].length - 1) {

        System.out.println("This provisionally substitutes error catching. Outlet (" + item[0] + "," + item[1] + ") is not correct.");
        outlets.remove(item);
        System.out.println("Remaining outlets: ");
        for (int[] atem: outlets) {
            System.out.print("(" + atem[0] + "," + atem[1] + ")\n");
        }
    }
    else {
        this.riverBasin[item[0]][item[1]] = 10;
    }
}

ArrayList アウトレットから「アイテム」を削除すると、エラーが発生します。

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at org.geoframe.ocn.Eden.setMultipleOutlet(Eden.java:135)
    at org.geoframe.ocn.Eden.main(Eden.java:205)

私は本当に完全には理解していません。ただし、イテレータを壊したのではないかと思います。正しい ?ArrayList 内の不要な要素を削除するにはどうすればよいでしょうか。

よろしくお願いします。

リカルド

4

9 に答える 9

4

Iterator を使用して ArrayList を反復する必要があります。次に、Iterator の remove メソッドを使用します。

于 2013-08-22T12:00:13.303 に答える
3

イテレータを明示的に使用して remove() を呼び出す必要があります。

final Iterator<int[]> iterator = outlets.iterator();
while (iterator.hasNext()) {
    final int[] item = iterator.next();
    ....
    if (...) {
        iterator.remove();
    }
}
于 2013-08-22T12:00:47.740 に答える
1

「for each」ループを使用して削除することはできません。代わりに Iterator を使用できます。

于 2013-08-22T12:01:59.500 に答える
1
for (int[] item: outlets) {}

これは高度な for ループです。内部的には、コレクションの反復子を作成して反復するのと同じことを行います。しかし、明示的に Iterator オブジェクトを取得しないと、コレクションから要素を削除する機能が失われます。これは、反復子が反復処理中にコレクションから要素を削除しようとすると、常に が取得されるためjava.util.ConcurrentModificationExceptionです。

したがって、あなたの場合、イテレータを取得して、 outlets.iterator();remove メソッドを使用し ますiterator.remove();

読み取り操作のみに高度なループを使用することをお勧めします。

于 2013-08-22T12:05:53.917 に答える
0

すでにいくつかの同様の質問と回答が投稿されています。

  1. 削除するアイテムのインデックスを追跡し、反復が完了したらそれらを削除できます。
  2. または、繰り返しながら保持したいすべてのものを新しいリストにコピーし、完了したら古いリストを破棄することもできます。

ソース:リスト反復中に java.util.List から要素を削除すると、ConcurrentModificationException がスローされますか? (hvgotcodes)

  1. toArray()アウトレットで関数を使用ArrayListし、配列で反復を実行して、ArrayListアウトレットから削除します。
于 2013-08-22T12:15:15.163 に答える
0

イテレータを介してエントリを削除する必要があります。これは、強化された for ループを使用できないことを意味します。

試す:

for(Iterator<int[]> outletsIterator = outlets.iterator(); outletsIterator.hasNext();){
    int[] item = outletsIterator.next();

    ...

    outletsIterator.remove();
}

注: ジェネリックと配列を混在させることはお勧めしません。使用を検討してください:List<List<Integer>>

于 2013-08-22T12:03:38.170 に答える
0

ここには、問題を解決する多くのコメントが既にあります。むしろ、コードに潜在的な問題があることがわかります。たとえば、インデックス 0 と 1 のみを処理する場合、ループに if チェックを入れるのはなぜですか。したがって、要素を反復して削除する必要さえありません。ソリューションの場合、イテレータはこれを行う1つの方法ですが、これにはGoogleコレクションAPIを使用することをお勧めします。そのような呼び出しの例は

Iterables.filter(yourCollectionToBeFiltered, predicate)

https://code.google.com/p/guava-libraries/でもっと調べることができます

于 2013-09-09T08:34:33.897 に答える