Java 遍历Arraylist时的ConcurrentModificationException(不删除)

Java 遍历Arraylist时的ConcurrentModificationException(不删除),java,android,exception,concurrency,Java,Android,Exception,Concurrency,我目前在遍历ArrayList时遇到问题。我在这里读了好几篇文章,但似乎没有什么能解决我的问题。这是我的密码: //restaurants contains a list of all restaurants and i want to filter them List<Restaurant> newList = new ArrayList<Restaurant>(); List<Restaurant> allRestaurants = new ArrayLi

我目前在遍历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;
                    }
                }
            }
我不明白。我没有在这一行操纵列表。为什么会发生这种情况?我如何修复它

else{
    newList = allRestaurants;
}
这几乎肯定是你的问题

newList
分配给
allRestaurants
然后添加到
newList
会导致您的修改

这是在
newList=allRestaurants
之后添加到
newList
的任何内容都将更新
allRestaurants
中的mod计数,从而更新您的错误。

在else分支中

else {
   newList = allRestaurants;
}
您将
newList
设置为
allRestaurants
。下一次修改
newList.add(餐厅)更改所有餐厅列表


调用
it.next()
时会引发异常,因为迭代器会检查其源是否已更改。

失败从以下内容开始:

newList = allRestaurants;
它将两个引用指向同一个列表(即您正在迭代的列表)。然后执行以下操作:

newList.add(restaurant);
修改列表。从
ConcurrentModificationException的javadoc中:

请注意,此异常并不总是表示对象已被其他线程并发修改。如果单个线程发出一系列违反对象约定的方法调用,该对象可能会引发此异常。例如,如果线程在使用fail fast迭代器迭代集合时直接修改集合,迭代器将引发此异常


你的问题在else条款中

         newList = allRestaurants;

这就是为什么会出现异常

无法更改用于循环内迭代的ArrayList;这就是ConcurrentModificationException()和
newList=allRestaurants所说的
新列表。添加(餐厅)
可能会更改列表
所有餐厅

所以你能做的就是

  • 创建另一个列表
  • 将要修改的项目放入该列表中
  • 将新列表(
    addAll
    removeAll
    )添加/删除到循环后的旧列表中

  • 查看更多信息。

    你说得对。我在那里也找到了。如果大小写
    Set keys=obj.keySet(),则它应该属于外部;对于(字符串键:键){}
    如何避免此异常?您可能不希望有嵌套的同步块
             newList = allRestaurants;