2012-01-03 67 views
2

我一直在研究這段代碼。這是我所希望發生的僞代碼:我一直在得到java.util.concurrentmodificationexception ..如何解決這個問題?

答。查看,如果部分(這是一個列表)大小爲0
b。如果段大小爲0,然後通過調用自動註冊學生節sections.add(newSection)
c.else如果段大小不爲零,檢查是否與時間衝突
d。若未有沒有衝突,然後通過調用sections.add(newSection)
招收學生節e.else什麼都不做

Java一直在對我拋出「java.util.concurrentmodificationexception」錯誤。我知道,我不應該在遍歷列表時改變ArrayList的大小,因爲它會修改迭代器。有沒有解決這個問題的另一種方法? :D

非常感謝。 非常感謝您的幫助。 :)

public String enrollsTo(Section newSection){ 


     StringBuffer result = new StringBuffer(); 

     String resultNegative = "Failed to enroll in this section."; 
     String resultPositive = "Successfully enrolled in section: " + newSection.getSectionName() + "."; 

     int previousSectionSize = sections.size(); 

     if(this.sections.isEmpty()){ 
      this.sections.add(newSection); 
      result.append(resultPositive); 
     }else{ 
      for(Iterator<Section> iterator = sections.iterator(); iterator.hasNext() ;){ 
       Section thisSection = iterator.next(); 

       if(thisSection.conflictsDayWith(newSection)==false && 
        thisSection.conflictsTimeWith(newSection)==false){ 
        this.sections.add(newSection); //<-- i believe the problem lies here. 
        result.append(resultPositive); 
       } 
      } 
     } 
//  if(this.sections.size() == previousSectionSize){ 
//   result.append(resultNegative); 
//  } 
     return result.toString(); 
    } 
+0

注:您的邏輯被打破了。而不是「如果沒有衝突」,你正在測試「每個不衝突的部分添加一個新的部分」。 – Howard 2012-01-03 16:36:32

+0

嗯..所以這就是爲什麼它看起來有點錯誤和怪異。你必須指出,得以改進它,謝謝指出。 :d – 2012-01-03 16:39:56

回答

0

從的Javadoc ConcurrentModificationException(我的強調):

此異常可能由已檢測到的併發 修改一個對象的當這樣的修改是不允許的方法被拋出。

例如,一個線程在另一個線程遍歷它時通常不允許修改Collection。一般而言,在這些情況下迭代的結果是不確定的。 某些迭代器實現(包括由JRE提供的所有通用 目的集合實現中的實現)可能選擇 如果檢測到此行爲則拋出此異常。迭代器做 這被稱爲快速迭代器,因爲它們很快就會失敗,並且會在未來確定一個未定的時間冒着任意的非確定性行爲的風險。

請注意,此例外情況並不總是表明某個對象已由另一個線程同時修改了 。如果單個線程 發出一系列方法調用違反對象的合約 ,該對象可能會拋出此異常。 例如,如果 線程在使用快速迭代器迭代 集合時直接修改集合,那麼迭代器將拋出此異常。

注意,快速失敗行爲不能得到保證,因爲它是一般 來講,不可能作出任何硬性保證 不同步併發修改的存在。盡力而爲,快速失敗操作拋出 ConcurrentModificationException。因此, 在編寫依賴於此例外的程序時是錯誤的: 其正確性:ConcurrentModificationException應僅用於 以檢測錯誤。

可能的解決方案:不是直接添加到您正在迭代的列表中,而是添加到臨時列表,然後在完成迭代後,執行addAll()

0

迭代收集時,您不能修改它。行this.sections.add(newSection);拋出異常。您可能需要使用一些布爾標誌來檢查條件

if(thisSection.conflictsDayWith(newSection)==false && 
        thisSection.conflictsTimeWith(newSection)==false) 

後for循環,如果你的布爾標誌是真實的,那麼你可以寫

this.sections.add(newSection); 
        result.append(resultPositive); 
1

不要做sections.add(newSection)您的循環內,因爲這是對當前迭代的集合的修改。

此外,您是否要在決定是否添加newSection之前檢查所有部分?也許是這樣的:

boolean conflict = false; 
for (...) { 
    if (/* check for conflict */) { 
    conflict = true; 
    break; 
    } 
} 
if (!conflict) { 
    sections.add(newSection); 
} 
0

你在你的假設是正確的,

this.sections.add(newSection); 

絕對是你的問題的根源。

最簡單的解決方案:有一個布爾值代表節的可用性。假設它可用,開始。如果您的迭代器中存在任何衝突,請將其設置爲false。在迭代器之後,如果該節可用(布爾值爲true),則添加該節。

0

我同意@sudocode你不想在每次找到一個不衝突的部分時都添加newSection。我會認爲,當你在調試器中執行代碼時,這是顯而易見的。 ;)

BTW另一個(比較模糊)的方式來做到這一點沒有一個標誌是

CHECK: { 
    for (...) { 
    if (/* check for conflict */) 
     break CHECK; 
    } 

    sections.add(newSection); 
}