我需要迭代一系列项目&有时会同时添加到该集合中。但是,如果我在迭代时添加,那么我只是通过突破迭代循环来开始迭代。从头开始重新开始迭代。然而,这导致了
ConcurrentModificationException
。 [下面的代码]
List<Integer> collection = new ArrayList<>();
for (Integer lobId: collection) {
..
if (someCondition) {
collection.add(something);
break;
}
}
我怎么能做上面的事情避免ConcurrentModificationException
?
仅使用Array
代替ArrayList
来避免此异常是否正确?
是否有任何类型的专门收藏?
-
我不想为这个arraylist创建一个新副本,因为除非完成某些要求,否则我会多次重复此整个迭代过程。每次创建一个新副本会带来一些额外的开销,如果可能的话,我想避免这种情况。
如果可能的话,我想维持一个排序顺序&amp;该集合中的唯一值。有没有可以在任何图书馆使用的东西?否则我可以在迭代过程结束时对其进行排序&amp;删除重复项。这对我也没问题。
答案 0 :(得分:4)
使用另一个集合添加,并在最后组合它们。
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);
答案 1 :(得分:3)
此代码无法导致ConcurrentModificationException,因为在添加元素后,您将断开循环并且不再使用迭代器
答案 2 :(得分:2)
ConcurrentModificationException
基本上意味着您使用Collection
迭代iterator
(尽管由增强的for
循环隐式定义)并在运行时使其无效更改Collection
本身。
您可以通过相同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;
}
}
答案 3 :(得分:2)
如果我理解你正确,你想迭代列表,如果有一些条件,你想打破迭代,一个项目并重新开始。
在这种情况下:
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);
}
如果其他人要在外面循环更改列表 - 您需要同步这些访问 - 阅读iterator thread safe,并在此处使用其他答案,例如复制列表或写入时的其他副本
答案 4 :(得分:-1)
不要为每个人使用,请使用旧的
for(int i=0; i<collection.size();i++)