简体   繁体   English

迭代此集合时如何避免ConcurrentModificationException?

[英]How to avoid ConcurrentModificationException while iterating this collection?

I need to iterate over a collection of items & sometimes add to that collection at the same time. 我需要迭代一组项目,有时同时添加到该集合。 However, incase I add while iterating then I just start the iteration from fresh by breaking out of iteration loop & restarting iteration from beginning. 但是,如果我在迭代时添加,那么我只是通过打破迭代循环并从头开始重新启动迭代来重新开始迭代。 However this leads to ConcurrentModificationException . 但是这会导致ConcurrentModificationException [code below] [下面的代码]

    List<Integer> collection = new ArrayList<>();
    for (Integer lobId: collection) {
         ..
         if (someCondition) {
             collection.add(something); 
             break; 
         }
    }

How could I possibly do something like above avoiding ConcurrentModificationException ? 我怎么能做上面这样的事情来避免ConcurrentModificationException

Would it be correct to simply use an Array instead of ArrayList to avoid this exception ? 简单地使用Array而不是ArrayList来避免这种异常是否正确? Is there any type of specialized collection for this ? 这有什么类型的专门收藏吗?

-- -

Edit: 编辑:

I dont want to create a new copy for this arraylist because I'm repeating this entire iteration process multiple times unless some requirement is completed. 我不想为这个arraylist创建一个新副本,因为除非完成某些要求,否则我会多次重复整个迭代过程。 Creating a new copy each time would bring in some extra overhead, which I would like to avoid if somehow possible. 每次创建一个新副本会带来一些额外的开销,如果可能的话,我想避免。

Also if possible I would like to maintain a sorted order & unique values in that collection. 如果可能的话,我想在该集合中维护一个排序顺序和唯一值。 Is there anything that is ready to use in any library? 有没有可以在任何图书馆使用的东西? Otherwise I could sort it at the end of iteration process & remove duplicates. 否则我可以在迭代过程结束时对其进行排序并删除重复项。 That will also do fine for me. 这对我也没问题。

Use another collection for the additions and combine them at the end. 使用另一个集合添加,并在最后组合它们。

List<Integer> collection = new ArrayList<>();
collection.add(...)
...
List<Integer> tempCollection = new ArrayList<>();    
for (Integer lobId: collection ) {
     ..
     if (someCondition) {
         tempCollection.add(something); 
         break; 
     }
}

collection.addAll(tempCollection);

这段代码不能导致ConcurrentModificationException,因为在你添加一个元素之后你就破坏了循环并且不再使用迭代器了

ConcurrentModificationException basically means that you're iterating over a Collection with one iterator (albeit implicitly defined by your enhanced for loop) and invalidating it on the fly by changing the Collection itself. ConcurrentModificationException基本上意味着您使用一个iterator迭代一个Collection (尽管由增强的for循环隐式定义),并通过更改Collection本身来动态地使其无效。 You can avoid this by doing the modifications via the same iterator : 您可以通过相同的iterator进行修改来避免这种情况:

List<Integer> collection = new ArrayList<>();
ListIterator<Integer> iter = collection.listIterator();
while (iter.hasNext()) {
     Integer currVal = iter.next();
     if (someCondition) {
         iter.add(something); // Note the addition is done on iter
         break; 
     }
}

if I understand you right, you want to iterate over the list , if some condition , you want to break the iteration , and an item and start fresh . 如果我理解你正确,你想迭代列表,如果有一些条件,你想打破迭代,一个项目并开始新鲜。

In the case do this: 在这种情况下这样做:

   List<Integer> collection = new ArrayList<>();
   boolean flag = false;
   Integer item = 
    for (Integer lobId: collection) {
         ..
         if (someCondition) {
             flag = true;
             item = something; 
             break; 
         }
    }

   if (flag){
      collection.add(item);
   }

if someone else is going to change the list outside out loop - you will need to sync those access - read iterator thread safe , and use the other answers here like copying the list or some other copy on write 如果其他人要在外面循环更改列表 - 你将需要同步这些访问 - 读取迭代器线程安全 ,并在这里使用其他答案,如复制列表或写入其他一些副本

不要每个使用,使用好旧

for(int i=0; i<collection.size();i++)

暂无
暂无

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

相关问题 如何在迭代 map.entrySet 时避免 ConcurrentModificationException - How to avoid ConcurrentModificationException while iterating over map.entrySet 如果在迭代时修改集合而不抛出 ConcurrentModificationException 会发生什么 - what will happen if modify a collection while iterating without throwing the ConcurrentModificationException 添加 ArrayList 元素时如何避免“ConcurrentModificationException”? - How to avoid "ConcurrentModificationException" while add ArrayList elements? 如何在迭代时仅避免ArrayList中的ConcurrentModificationException? - How do I avoid ConcurrentModificationException in ArrayList ONLY when iterating? 迭代地图并更改值时如何避免ConcurrentModificationException? - How to avoid ConcurrentModificationException when iterating over a map and changing values? 通过HashMap迭代时出现ConcurrentModificationException - ConcurrentModificationException while iterating through HashMap 如何在迭代Hashmap时获取ConcurrentModificationException? - How I can get ConcurrentModificationException while iterating Hashmap? 在这种情况下如何避免 ConcurrentModificationException? - How to Avoid ConcurrentModificationException in that case? Java 迭代集合在保存后抛出 ConcurrentModificationException - Java iterating collection throws ConcurrentModificationException after Save 如何在并发线程中操作`values()`和`put()`时避免使用HashMap“ConcurrentModificationException”? - How to avoid HashMap “ConcurrentModificationException” while manipulating `values()` and `put()` in concurrent threads?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM