【发布时间】:2011-10-20 23:17:26
【问题描述】:
如果我在使用 for-each 循环迭代集合时修改集合,它会给出ConcurrentModificationException。有什么解决办法吗?
【问题讨论】:
标签: java collections concurrentmodification
如果我在使用 for-each 循环迭代集合时修改集合,它会给出ConcurrentModificationException。有什么解决办法吗?
【问题讨论】:
标签: java collections concurrentmodification
这是在迭代期间修改集合的唯一安全方法。如需更多信息,请参阅The Collection Interface 教程。
如果您还需要在迭代时添加元素,请使用ListIterator。
【讨论】:
一种解决方法是保存您的更改并在循环后添加/删除它们。
例如:
List<Item> toRemove = new LinkedList<Item>();
for(Item it:items){
if(remove){
toRemove.add(it);
}
}
items.removeAll(toRemove);
【讨论】:
第二种解决方法是使用一个集合类,它的迭代器不会给出异常。比如ConcurrentLinkedQueue、ConcurrentHashMap等等。
这些通过为迭代器提供较弱的一致性模型来避免引发异常的需要。 (当然,您需要了解这些模型,并确定它们是否适合您的应用程序。)
它们通常比非并发集合慢一点,但如果存在严重争用,它们比同步集合包装器快。
【讨论】:
如果你只是想从集合中移除元素,你可以使用 Iterator 而不是 Iterable。
否则,您可以做的不是迭代原始集合,而是首先制作列表的副本。例如,如果您的集合是一个列表,那么您可以创建一个新的 ArrayList(originList) 并对其进行迭代。应该对原始列表进行修改。
另一种可能更适合您的用例的替代方法不是使用 for-each,而是使用传统的 for-。
【讨论】: