![](/img/trans.png)
[英]Removing element while iterating through it. removeIf result in ConcurrentModificationException
[英]ConcurrentModificationException while iterating through Arraylist (not removing)
我目前在迭代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-loop)。 我甚至已经同步了整个方法,仍然得到一个例外。
例外情况发生在以下行:
Restaurant restaurant = it.next();
我不明白。 我没有操纵这一行中的列表。 为什么会发生这种情况,我该如何解决?
else{
newList = allRestaurants;
}
这几乎肯定是你的问题。
将newList
分配给allRestaurants
然后添加到newList
会导致您的编辑。
这是后newList = allRestaurants
任何添加到newList
将更新MOD计数allRestaurants
,因此你的错误。
在else分支中
else {
newList = allRestaurants;
}
您将newList
设置为allRestaurants
。 下一个修改newList.add(restaurant);
更改allRestaurants列表。
调用it.next()
时会抛出异常,因为迭代器会检查其源是否已更改。
失败始于:
newList = allRestaurants;
它指向两个引用相同列表(即您正在迭代的那个)。 然后,您执行以下操作:
newList.add(restaurant);
修改列表。 从ConcurrentModificationException
的javadoc:
请注意,此异常并不总是表示某个对象已被另一个线程同时修改。 如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常。 例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。
你的问题出在else子句中。
newList = allRestaurants;
这就是你获得例外的原因
您不能更改循环内用于迭代的ArrayList; 这就是ConcurrentModificationException所说的( http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ConcurrentModificationException.html )和newList = allRestaurants;
加上newList.add(restaurant);
确实有可能改变列表allRestaurants
。
所以你能做的就是
addAll
或removeAll
)到旧列表 查看http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html了解更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.