2013-03-13 92 views
3

我目前有迭代通過ArrayList的問題。我在這裏看過幾篇文章,但似乎沒有解決我的問題。這裏是我的代碼:ConcurrentModificationException迭代通過Arraylist(不刪除)

//restaurants contains a list of all restaurants and i want to filter them 
List<Restaurant> newList = new ArrayList<Restaurant>(); 
List<Restaurant> allRestaurants = new ArrayList<Restaurant>(restaurants); 
if (query != null && query.length() > 0 && !query.equals("*")) { 
      synchronized (allRestaurants) { 
       for (Iterator<Restaurant> it = allRestaurants.iterator(); it 
         .hasNext();) { 
        Restaurant restaurant = it.next(); 
        if (restaurant.getCity().contains(query)) { 
         synchronized (newList) { 
          newList.add(restaurant); 
         } 
        } else { 
         newList = allRestaurants; 
        } 
       } 
      } 

這是代碼是由我修改與一些想法,我已經在這裏讀(同步,使用迭代器代替的for-each循環)。我甚至已經對整個方法進行了同步,但仍然得到一個異常。

唯一的例外是發生在下面一行:

Restaurant restaurant = it.next(); 

,我不明白。我不會操縱這一行中的列表。爲什麼會發生這種情況,我該如何解決這個問題?

+0

你可能不想有一個嵌套的同步塊 – 2013-03-13 20:29:01

回答

4
else{ 
    newList = allRestaurants; 
} 

這幾乎肯定是您的問題。

newList指定爲allRestaurants然後將其添加到newList正在導致您的協同作業。

newList = allRestaurants之後的任何加到newList都會更新allRestaurants中的mod計數,從而導致你的錯誤。

+0

你是對的..我也在那裏發現它。它應該屬於外部的情況 – MrHill 2013-03-13 20:28:45

0

在else分支

else { 
    newList = allRestaurants; 
} 

您設置newListallRestaurants。下一次修改newList.add(restaurant);將更改allRestaurants-list。

調用it.next()時拋出異常,因爲迭代器會檢查其源是否已更改。

newList = allRestaurants; 

指向同一列表兩個引用(即一個你迭代):

0

失敗開頭。然後執行以下操作:

newList.add(restaurant); 

修改列表。從ConcurrentModificationException的javadoc:

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

0

你的問題在else子句中。

  newList = allRestaurants; 

這就是爲什麼你會得到異常

0

你不能改變一個用於在一個循環中迭代ArrayList的; ConcurrentModificationException所述(http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ConcurrentModificationException.html)和newList = allRestaurants;newList.add(restaurant);確實可能會更改列表allRestaurants

所以,你可以做的是

  1. 創建另一個列表
  2. 將商品放入該列表修改
  3. 添加/刪除新的列表(addAllremoveAll),以舊後一個迴路

查看更多http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html