2012-01-11 3 views
1

私はJavaを初めて使用しています。特に、リストを反復して要素を変更するのは難しいです。私は何十もの似たような質問をしましたが、多くの試みの後には何も働かなかった。 次のコードサンプルでは、​​例外がスローされます。私はスレッドが1つしかないので、同時スレッドには関係しません。 Netbeansの出力サイス例外がライン5に発生する(このCustomerData顧客= i.next();):全コードのみ要素がTAGIDに一致し、それがない場合は、2を交換しているかどうかをチェックすることになっている別のConcurrentModificationException

CustomerData tempCustomer = new CustomerData("",tagID,0); 
tempCustomer.setName(name); 
tempCustomer.setSize(size); 
for(ListIterator<CustomerData> i = customers.listIterator(); i.hasNext();) 
{ 
    CustomerData customer = i.next(); 
    if(customer.getTagID().contains(tagID)) 
    { 
     Object[] options = {"overwrite", "do not overwrite"}; 
     int n = JOptionPane.showOptionDialog(rootPane, 
              "TagID already exists. overwrite?", 
              "?", 
              JOptionPane.YES_NO_OPTION, 
              JOptionPane.QUESTION_MESSAGE, 
              null, 
              options, 
              rootPane); 
     if (n == JOptionPane.YES_OPTION){ 
      i.set(tempCustomer); 
     } 
    } 
    else{ 
     addCustomer(); 
    } 
} 

値(名前とサイズ)が含まれています。当初はsetName()setSize()を要素のforループの内側で使用しようとしましたが、それがうまくいかず、他の関連する質問を読んだあと、ループの前に一時オブジェクトに値を割り当て、イテレータのsetメソッドを使って現在の素子。しかし、まだ成功しておらず、例外が5行目以降に来るので、それは決してそれを達成できないように思われます。

答えて

2

問題は、おそらく、この行です:

 addCustomer(); 

はあなたがそれを反復処理の真ん中にいる間 customersを変更しようとしています。これは許可されていません。

とにかく、それは論理エラーのように思える:おそらくあなたはループの後、一度だけaddCustomerを呼びたい、顧客が権利tagIDがなかったが、あなたの現在のコードは、各顧客ためaddCustomerを呼び出そうとした場合間違ったtagIDと一緒に。そのため、ループ中にboolean変数を使用して、一致する顧客があるかどうかを追跡し、ループの後に適切な場合はaddCustomerを呼び出します。

+0

ああ!あなたが正しいです。私はいつもif部分を見ていて、関数のelse部分では見ていませんでした。今、私は 'addCustomer()'を 'i.add'に置き換えました。これはうまくいきます。さらに、NetBeansは5行目で例外が発生したと私に混乱させました。私はif-else文全体を間違って数えると思います。 3つの答えはすべて正しく、質問をする前に私が読んだものです。私は論理エラーのアドバイスのためにあなたのものを正しいものとしてマークします。次はそれに乗ります。ありがとうございました! – rbx

0

ConcurentModificationExceptionは、オブジェクトが別のスレッドによって同時に変更されたことを常に示すわけではありません。

あなたのケースでは、次のような問題が発生する可能性があります(addCustomerメソッドで推測する):コレクションのイテレータを取得してから、このコレクションを変更しています。コレクションが変更されるため、イテレータは無効になり、例外がスローされます。

私の提案は、あなたの反復が終了したときに元の顧客リストに追加する顧客のテンポラリーリストを作成することです。

0

javadocsで述べたように:私はそれがcustomersオブジェクトを変更addCustomer()を呼び出した後発生していると思います

if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception.

。新しく追加されたオブジェクトは、ループの終わりまで別のコレクションに保持するか、ループから抜け出して追加後に再起動することができます。

関連する問題