-2

同じリストで2つの異なるイテレータを使用していて、リストの1つを変更しているため、ConcurrentModificationExceptionをスローする次のコードがあります。したがって、他のイテレータがリストを変更したため、リストを読み込むときに2番目のイテレータが例外をスローします。Javaの反復子がConcurrentModification例外をスローするタイミングを知る方法

List<Integer> list = new ArrayList<>(); 

    populate(list);//A method that adds integers to list 

    ListIterator<Integer> iterator1 = list.listIterator(); 
    ListIterator<Integer> iterator2 = list.listIterator(); 

    while (iterator1.hasNext()) { 
     if(iterator1.next() < 5) 
      iterator1.remove(); 
    } 

    while (iterator2.hasNext()){ 
     if(iterator2.next() < 5) { 
     //Call handler 
     } 
    } 

私の質問はどのようiterator2が、それはまだiterator1によって除去された要素に到達していない場合listは、他のいくつかの反復子が変更されているいることを、内部を知っているんでしょうか?他のiteratorlistに変異を起こしていることがどのようにわかりますか? 1つの方法ではサイズを把握することができますが、他のイテレータでは要素を置き換えることができるので、それは理由ではありません。

+0

なぜ気になりますか?リストを変更する前にイテレーターを作成しました。おそらく "汚い"フラグがありますが、なぜこのように動作するようにコードしたいのでしょうか? – stdunbar

+1

私はこのようなコードを動作させたくありません。しかし、私はこのシナリオがどのように検出されたかを知っています。 –

+0

ソースを自由に利用できます! –

答えて

3

このような質問に答える良い方法は、ソースコードを見ることです(例:the source code for ArrayList)。 ConcurrentModificationExceptionを検索してください。

あなたは物事がなく、このように動作することを伝えることができるはずです。

  • コレクションオブジェクトはゼロから始まり、追加または削除、または同様の操作が発生するたびに増加修正回数を、持っています。
  • イテレータオブジェクトが作成されると、イテレータ内にコレクションの現在の変更回数が格納されます。
  • イテレーターが使用されるたびに、イテレーターが作成されたときに取得したモッズ・カウントと照合して、コレクションのモジュール数をチェックします。これらの値が異なる場合、例外がスローされます。

リストでiterator1の操作を削除すると、リストの構造上の操作回数(modCount)が変更されます。 iterator2を削除するように要求された場合、リストの現在のMODカウントとは異なり、最初は0として受信されたexpectedModCountが表示されます。

it.removeは特殊なケースです。イテレータが削除自体を行うと、それに応じてexpectedModCountが調整され、基になるリストと同期します。

+0

アプローチを得ました。ありがとう! –

+0

あなたは大歓迎です。ソースコードはここでは非常に便利です。変数やコメントの名前は素晴らしいです。 BTW私はもう少し答えを加えました---誰か(正しく)downvoted、私は、イテレータが削除操作自体を行うことについての専門知識を省いたので、私は思います。それは基本的な考え方を変えるものではありませんが、ここで完全であることは良いことです。 –

関連する問題