2

ConcurrentModificationException次のコードを実行すると、プログラムがスローします。いくつかの調査を通じて、反復子ループではリスト内の要素を追加または削除できないことがわかりました。の要素を削除するにはどうすればよいList<Bean>ですか?

for (Iterator<Entry<String, List<Bean>>> iterator = dataMap.entrySet().iterator(); iterator.hasNext();) {
    Entry<String, List<Bean>> entry = (Entry<String, List<Bean>>)iterator.next();
    List<Bean> dateWiseValues = (List<Bean>) entry.getValue();
    int j = 0;
    for (Bean statBean : dateWiseValues) {
        for (int i = 0; i < commonElements.size(); i++) {
            if(statBean.getDate().equalsIgnoreCase(commonElements.get(i))) {
                //remove the bean
                entry.getValue().remove(j);
            }
        }
        j++;
    }
} 
4

2 に答える 2

5

範囲ベースの forループ オーバーdateWiseValuesを使用するのではなく、Iterator明示的に を使用して、代わりに を呼び出すことができますIterator#remove()

for (final Iterator<? extends Bean> it = dateWiseValues.iterator();
     it.hasNext();) {
  final Bean statBean = it.next();
  for (int i = 0, last = commonElements.size(); i != last; ++i)
    if (statBean.getDate().equalsIgnoreCase(commonElements.get(i)))                
      it.remove();
}

一般に、コレクションの反復子の 1 つを使用して反復処理を行う限り、要素をそのコレクションから削除しても安全です。


の具体的な型はわかりませんがdateWiseValues、 のサブタイプであることはわかっていListます。実装する 2 つの一般的な具象型ListArrayListLinkedListです。これらの各クラスの散文クラスレベルのドキュメントには、次の警告が含まれています。

このクラスのiteratorおよびlistIteratorメソッドによって返される反復子はフェイルファストです。反復子が作成された後、Iterator独自のremoveまたはaddメソッド以外の方法でリストが構造的に変更された場合、反復子は をスローしConcurrentModificationExceptionます。したがって、同時変更に直面した場合、反復子は、将来の不確定な時点で恣意的で非決定論的な動作を危険にさらすのではなく、迅速かつ明確に失敗します。

これは、反復中に for ミューテーションを使用する必要があることを警告していることに注意してください。そうしないと、次に同じ、または同じ基になるリストを歩いている他の反復子を使用するときにIterator#remove()スローされることに注意してください。ConcurrentModificationException

于 2013-04-20T00:02:32.020 に答える
2

拡張forループを使用すると、Iteratorバックグラウンドで暗黙的に が使用されます。これは、外側のループで定義した明示的なイテレータではなく、 をIteratorスローすることです。を呼び出して現在のリスト項目を削除し、.ConcurrentModificationExceptioniteratorforIteratorIterator#remove()ConcurrentModificationException

あなたの2つのオプション:

  • ループforと を明示的に使用するように拡張ループを書き直してから、アイテムを削除するときに呼び出します。whileIteratorremove()
  • List削除するアイテムの を作成します。そのアイテムを削除する場合は、削除するアイテムaddの一覧に移動します。次に、 反復が終了たらremoveAll、元のリストを呼び出して、削除するすべてのアイテムを削除します。
于 2013-04-20T00:02:33.317 に答える