如果我在使用for-each循环迭代它时修改Collection,它会给出ConcurrentModificationException
。有没有解决方法?
答案 0 :(得分:38)
这是在迭代期间修改集合的唯一安全方法。有关更多信息,请参阅The Collection Interface教程。
如果您还需要在迭代时添加元素,请使用ListIterator
。
答案 1 :(得分:10)
一种解决方法是保存更改并在循环后添加/删除它们。
例如:
List<Item> toRemove = new LinkedList<Item>();
for(Item it:items){
if(remove){
toRemove.add(it);
}
}
items.removeAll(toRemove);
答案 2 :(得分:3)
第二种解决方法是使用一个集合类,其迭代器不会给出异常。例如ConcurrentLinkedQueue
,ConcurrentHashMap
等等。
通过为迭代器提供较弱的一致性模型,避免了抛出异常的需要。 (当然,您需要了解这些模型,并确定它们是否适合您的应用。)
它们通常比非并发集合慢一点,但如果存在重大争用,则比同步集合包装器更快。
答案 3 :(得分:1)
如果您只想从集合中删除元素,可以使用Iterator而不是Iterable。
否则,您可以做的不是迭代原始集合,而是先复制列表。例如,如果您的集合是一个列表,那么您可以创建一个新的ArrayList(originaList)并迭代它。修改应该在原始列表中进行。
另一种可能更适合您的用例的替代方案,不是使用for-each而是传统的 - 。