2011-08-16 16 views
3

我有一個List,並且我想循環訪問該List並在某些情況下刪除某些記錄庫。我在做什麼Java:在for-each循環中刪除List中的記錄時發生異常

public void foo(List<Bar> recordList){ 
    for(Bar bar : recordList){ 
     if(bar.someCondition()){ 
       recordList.remove(bar); 
     } 
    } 
} 

此代碼生成異常。如果我使用iterator然後正常工作

public void foo(List<Bar> recordList){ 
    Iterator<Bar> iter = recordList.iterator(); 
    while(iter.hasNext()){ 
     Bar bar = iter.next(); 
     if(bar.someCondition()){ 
       iter.remove(); 
     } 
    } 
} 

我想我的問題:

  1. 爲什麼代碼的第一塊不起作用?

  2. 如何使第一段代碼起作用?

+0

你忘了返回類型'void' –

+1

http://stackoverflow.com/questions/1921104/loop-on-list-with-remove和http://stackoverflow.com/questions/223918/java-efficient-等價於去除 - 迭代 - 收集 –

回答

6
  1. 它不工作,因爲你正在修改的集合,而在它的迭代。這意味着你正在改變它的狀態並同時閱讀它。這引起了收集者意外的行爲,並且爲了防止數據損壞,拋出異常。

  2. 你不會使它工作。你必須使用迭代器。

+0

謝謝你Vivien –

10

這個文件很清楚。

http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html

此類的iterator和listIterator方法返回的迭代器是快速失敗的:如果列表隨時結構上修改迭代器創建之後,以任何方式除非通過迭代器自身的remove或添加方法,迭代器將拋出一個ConcurrentModificationException。因此,面對併發修改,迭代器快速而乾淨地失敗,而不是在將來未定的時間冒着任意的,非確定性的行爲冒險。

+0

非常感謝你,Kal。 –