3

私は以下のコードを持っています

Map<String, Integer> buyingItemEnumerationMap = this.toBuyItemEnumeration;
for (Entry<String, Integer> item : buyingItemEnumerationMap.entrySet()) {
   if(RandomEngine.boolChance(50)){ //will delete?
    buyingItemEnumerationMap.remove(item.getKey());
   }
   if(buyingItemEnumerationMap.size() == 1){
    break;
   }
}

今、私はアンドロイドゲームを扱っており、上記のコードはマルチスレッドで実行されています。今、私は例外を抱えていますjava.util.ConcurrentModificationException。問題を解決する方法についてはすでに調査しましたが、うまくいかないようです。上記のコードで行っていることは、エントリをランダムに削除することです。どうすればそこに実装できますか?

4

4 に答える 4

9

を使用しない限り、反復中にコレクションから要素を削除することはできませんIterator

これが例外の原因です。

buyingItemEnumerationMap.remove(item.getKey());

次のようにコレクションを反復しながら要素を削除するには、Iterator#remove()を使用します

Iterator<Map.Entry<String, Integer>> iterator = 
                           buyingItemEnumerationMap.entrySet().iterator();
while (iterator.hasNext()) {
   Map.Entry<String, Integer> item = iterator.next();
   if(RandomEngine.boolChance(50)){ //will delete?
      iterator.remove();
   }
   //..
}

EDIT : (OP のコメントに応じて)
はい、 HashMap.entrySet()によって返されたIterator#remove()上でて、基になるものに反映されます。ここで JavaDoc を引用します。SetMapSet

このマップに含まれるマッピングの Set ビューを返します。セットはマップに支えられているため、マップへの変更はセットに反映され、その逆も同様です。

于 2013-07-17T07:26:13.963 に答える
6

を使用しIteratorます。

Iterator<Map.Entry<String, Integer>> iter = this.toBuyItemEnumeration;
while (iter.hasNext()) {
    Map.Entry<String, Integer> entry = iter.next();
    if (some-condition){
        iter.remove();
    }
}

使い方 ?

のjavadocはConcurrentModificationException言う:

1 つのスレッドが、オブジェクトのコントラクトに違反する一連のメソッド呼び出しを発行すると、オブジェクトはこの例外をスローする可能性があります。たとえば、フェイルファスト反復子を使用してコレクションを反復処理しているときに、スレッドがコレクションを直接変更すると、反復子はこの例外をスローします。

フィールドint expectedModCountはフィールドと等しくなるように開始されprotected transient int modCount = 0;(これはコレクションとマップに有効です)、modCountオブジェクトの構造変更を追跡します。modCount反復のある時点で が等しくない場合expectedModCount、 aConcurrentModificationExceptionがスローされます。

を使用Iteratorしてマップ/コレクションの構造を変更する (要素を削除するなど) ことで、削除操作が適切に実行されるようにします。たとえば、modCountは と等しくなりexpectedModCountます。

于 2013-07-17T07:26:44.090 に答える
0

forEach ループで iterator を使用し、 iterator.remove(); を使用します。

于 2013-07-17T07:26:54.453 に答える