2013-03-13 94 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