2012-01-11 44 views
1

我是Java新手,特別是遍歷列表並修改它的元素。我經歷了幾十個類似的問題,但經過多次嘗試後,沒有任何工作。 在以下代碼示例中引發了異常。它與併發線程無關,因爲我只有一個線程。在第5行出現異常Netbeans的輸出賽斯(CustomerData顧客= i.next();):另一個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(); 
    } 
} 

整個代碼僅應該檢查元件具有匹配TAGID並且如果是的話,替代兩個值(名稱和大小)。最初,我嘗試在元素的for循環中使用setName()setSize(),但在它沒有工作並且在閱讀其他相關問題後,我在循環之前將值分配給了臨時對象,並且使用迭代器的set方法替換current元件。但仍然沒有成功,它甚至似乎從來沒有得到那麼多,因爲第5行之後出現異常......

回答

2

的問題大概是這行:

 addCustomer(); 

試圖修改customers當你在遍歷它的中間是。這是不允許的。

不管怎樣,這似乎是一個邏輯錯誤:想必你想叫addCustomer只有一次,在循環後,如果沒有客戶有正確的tagID,但當前的代碼試圖調用addCustomer每個客戶與錯誤的tagID。因此,您需要在循環過程中使用boolean變量來跟蹤是否有任何客戶匹配,然後在循環之後,在適當的情況下調用addCustomer。在javadocs提到

+0

啊!你是對的。我一直在看if-part,而不是在函數的其他部分。現在我用'i.add'替換了'addCustomer()',它的工作原理......重新審視代碼會產生奇蹟。此外,NetBeans通過告訴第5行出現異常讓我困惑。我想它將整個if-else語句算作錯誤。所有三個答案都是對的,而我在提問之前閱讀的答案都是正確的。我會將您的建議標記爲邏輯錯誤。接下來會繼續。謝謝大家! – rbx 2012-01-11 01:31:12

0

ConcurentModificationException並不總是表明某個對象已被另一個線程同時修改過。

在你的情況下,問題可能在以下(通過addCustomer方法猜測):你正在獲取集合的迭代器,然後修改這個集合。由於集合被修改,迭代器變得無效並拋出異常。

我的建議是創建temproray客戶列表,當您的迭代完成後,您將添加到您的原始客戶列表中。

0

如:

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.

我估計是到addCustomer()一個呼叫,其修改customers對象之後發生。您可以將新添加的對象保存在不同的集合中,直到循環結束或跳出循環並在添加後重新啓動。

相關問題