简体   繁体   English

迭代Arraylist时的ConcurrentModificationException(不删除)

[英]ConcurrentModificationException while iterating through Arraylist (not removing)

I currently have a problem with iterating through an ArrayList. 我目前在迭代ArrayList时遇到问题。 I've read several posts here, but nothing seem to have resolved my problem. 我在这里看过几篇文章,但似乎没有解决我的问题。 Here is my code: 这是我的代码:

//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;
                    }
                }
            }

This is code was modified by me with several ideas i've read here (synchronized, using iterator instead of for-each-loop). 这是我修改过的代码,我在这里读过几个想法(同步,使用迭代器而不是for-each-loop)。 I even have synchronized the whole method and still get an exception. 我甚至已经同步了整个方法,仍然得到一个例外。

The exception is happening in following line: 例外情况发生在以下行:

Restaurant restaurant = it.next();

which I don't understand. 我不明白。 I am not manipulating the list in this line. 我没有操纵这一行中的列表。 Why is this happening and how can i fix it? 为什么会发生这种情况,我该如何解决?

else{
    newList = allRestaurants;
}

That is almost certainly your issue. 这几乎肯定是你的问题。

Assigning newList to allRestaurants then adding to newList is causing your comodification. newList分配给allRestaurants然后添加到newList会导致您的编辑。

That is after newList = allRestaurants any add to newList will update the mod count in allRestaurants and thus your error. 这是后newList = allRestaurants任何添加到newList将更新MOD计数allRestaurants ,因此你的错误。

In the else branch 在else分支中

else {
   newList = allRestaurants;
}

You set newList to be allRestaurants . 您将newList设置为allRestaurants The next modification newList.add(restaurant); 下一个修改newList.add(restaurant); changes the allRestaurants-list. 更改allRestaurants列表。

The exception is thrown when it.next() is called, because then the iterator checks if its source was changed. 调用it.next()时会抛出异常,因为迭代器会检查其源是否已更改。

The failure starts with: 失败始于:

newList = allRestaurants;

which points both references to the same list (ie the one you are iterating over). 它指向两个引用相同列表(即您正在迭代的那个)。 You then do the following: 然后,您执行以下操作:

newList.add(restaurant);

modifying the list. 修改列表。 From the javadoc of ConcurrentModificationException : ConcurrentModificationException的javadoc:

Note that this exception does not always indicate that an object has been concurrently modified by a different thread. 请注意,此异常并不总是表示某个对象已被另一个线程同时修改。 If a single thread issues a sequence of method invocations that violates the contract of an object, the object may throw this exception. 如果单个线程发出违反对象合同的一系列方法调用,则该对象可能会抛出此异常。 For example, if a thread modifies a collection directly while it is iterating over the collection with a fail-fast iterator, the iterator will throw this exception. 例如,如果线程在使用失败快速迭代器迭代集合时直接修改集合,则迭代器将抛出此异常。

Your problem is in the else clause. 你的问题出在else子句中。

         newList = allRestaurants;

That's why you get exceptions 这就是你获得例外的原因

You can't change the ArrayList that is used for iteration inside a loop; 您不能更改循环内用于迭代的ArrayList; that is what ConcurrentModificationException says ( http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ConcurrentModificationException.html ) and newList = allRestaurants; 这就是ConcurrentModificationException所说的( http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ConcurrentModificationException.html )和newList = allRestaurants; plus newList.add(restaurant); 加上newList.add(restaurant); does potentially change the list allRestaurants . 确实有可能改变列表allRestaurants

So what you could do is 所以你能做的就是

  1. create another list 创建另一个列表
  2. put items to modify in that list 将项目放在该列表中进行修改
  3. add/remove the new list ( addAll or removeAll ) to your old one after the loop 在循环之后添加/删除新列表( addAllremoveAll )到旧列表

Check out http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html for more. 查看http://www.javacodegeeks.com/2011/05/avoid-concurrentmodificationexception.html了解更多信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在遍历元素时删除元素。 removeIf 导致 ConcurrentModificationException - Removing element while iterating through it. removeIf result in ConcurrentModificationException 通过HashMap迭代时出现ConcurrentModificationException - ConcurrentModificationException while iterating through HashMap 迭代ArrayList时出现ConcurrentModificationException <Integer> - ConcurrentModificationException when iterating through an ArrayList <Integer> 迭代并从 ArrayList 中删除元素时如何避免 java.util.ConcurrentModificationException - How to avoid java.util.ConcurrentModificationException when iterating through and removing elements from an ArrayList 遍历列表但未修改列表时发生ConcurrentModificationException - ConcurrentModificationException while iterating through a list but not modifying it 遍历List时发生ConcurrentModificationException,尽管未对其进行任何修改 - ConcurrentModificationException while iterating through List, altough not modifying it 如果我们在迭代时最后在ArrayList中添加元素,则抛出ConcurrentModificationException - Throwing ConcurrentModificationException if we add elements in ArrayList at the end while iterating 遍历集合,在循环中删除对象时避免 ConcurrentModificationException - Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop 迭代ArrayList时Java ConcurrentModificationException - Java ConcurrentModificationException when iterating ArrayList Java ConcurrentModificationException:是否可以在迭代时向哈希表添加元素? - Java ConcurrentModificationException: Is it possible to add elements to a hashtable while iterating through it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM