1
String input from keyboard
Vector<String> myVector = new Vector<String>(someArray.length);   //assume Vector is populated
Iterator<String> itr = myVector.iterator();

for loop begins
    while(itr.hasNext() && itr.next().equals(input)){
       itr.remove();
    }

    ...

    while(itr.hasNext()    // is this the problem source?
     run more code  

for loop ends

現在の要素が文字列と等しい場合、inputその要素を削除します。それ以外の場合は、繰り返しを続けます。ここで同時に例外が発生し続けます。

他に何をすべきですか?itr.nextを別の場所に移動する必要がありますか?

質問:現在のVector要素がtargetと等しい場合、Vectorから削除するようなロジックが必要です。どうやってやるの?

4

5 に答える 5

2

ConcurrentModificationExceptionコレクションを反復処理し、コレクションから要素を慎重に削除しない場合、Aがスローされる可能性があります。

削除する要素を含む別の要素を作成し、ループの実行が終了した後でListそれらをすべて元の要素から削除することをお勧めします。Vector

その他の提案:

リストのコピーを繰り返すこともできます。

foreachループを使用します。

for (String value : myVector) {
  ...
}
于 2012-09-17T19:58:35.557 に答える
2

イテレータを介してアイテムを削除することは正当であるため、なぜ同時変更の例外が発生するのかわかりません。ドキュメントによると、

Iteratorが作成された後、いつでもVectorが構造的に変更された場合、Iterator自体のremoveまたはaddメソッド以外の方法で、IteratorはをスローしConcurrentModificationExceptionます。

ターゲットに等しいすべての要素をベクトルから削除することについての質問に答えるには、最も簡単な解決策はVectorremoveAllメソッドを使用することです。

myVector.removeAll(Collections.singletonList(input));
于 2012-09-17T20:19:09.173 に答える
1

ベクトルの内容を初期化しましたか?コンストラクターで長さを設定していますが、実際に文字列を追加していることがわかりません。これにより、NullPointerExceptionが発生します。

おそらく、次のコマンドでベクターを初期化する必要があります:Arrays.asList(someArray)

正しいベクトルを使用する場合、forループ内にイテレーターのwhileループを設定する必要はありません。

このようなものが機能するはずです:

String[] someArray = new String[]{ "A", "B", "C" };
Vector<String> myVector = new Vector<String>(Arrays.asList(someArray));
Iterator<String> itr = myVector.iterator();
while(itr.hasNext()){
   String myString = itr.next();
   if (myString.equals(input)) itr.remove();
}

編集発生した例外の理由は、.nextメソッドを誤って呼び出したことが原因である可能性があります。.nextメソッドは、各呼び出しの後に1hasNext回だけ呼び出す必要があり、.removeは、各呼び出しの後に1回だけ呼び出す必要があり.nextます。コードの詳細を省略しているため、問題を正確に特定することは困難です。しかし、全体として、forループは必要ありません。whileループで十分ですが、ifステートメント内にあるべきではありませんhasNext next

イテレータを使用して反復する正しい方法は、(擬似コードで)次のとおりです。

while (iterator has more items) {
    get the next item
    do something with the item (remove it if it should be removed, or handle it in another way)
}
于 2012-09-17T19:59:31.560 に答える
0

イテレータ全体を避けたいだけです。これはあなたが望むことをするはずです:

  while (myVector.remove(input)) {
    // this should get them all
  }
于 2012-09-17T20:07:31.930 に答える
0

次のようにベクターをラップしてみてください。

Vector vector = Collections.synchronizedCollection(vector);

およびjavadocの簡単な説明:

指定されたコレクションに基づく同期された(スレッドセーフな)コレクションを返します。シリアルアクセスを保証するために、バッキングコレクションへのすべてのアクセスが返されたコレクションを介して実行されることが重要です。

返されたコレクションを反復処理するときは、ユーザーが手動で同期する必要があります。

Collection c =
 Collections.synchronizedCollection(myCollection);
      ...   synchronized(c) {
       Iterator i = c.iterator(); // Must be in the synchronized block
       while (i.hasNext())
          foo(i.next());   }
于 2012-09-17T20:10:17.530 に答える