如何在不使用ConcurrentModificationException的情况下迭代使用for-each循环的同时修改Collection?

如果我使用for-each循环遍历它时修改了一个集合,它会给出ConcurrentModificationException 。 有没有解决办法?

使用Iterator#remove

这是在迭代期间修改集合的唯一安全方法。 有关更多信息,请参阅集合接口教程。

如果您还需要在迭代时添加元素的function,请使用ListIterator

解决方法之一是保存您的更改并在循环后添加/删除它们。

例如:

 List<Item> toRemove = new LinkedList<Item>(); for(Item it:items){ if(remove){ toRemove.add(it); } } items.removeAll(toRemove); 

第二个解决方法是使用迭代器不会发出exception的集合类。 例如ConcurrentLinkedQueueConcurrentHashMap等等。

这些避免了通过为迭代器提供较弱的一致性模型来抛出exception。 (当然,您需要了解这些模型,并决定它们是否适合您的应用程序。)

它们通常比非并发集合稍慢,但是如果存在显着的争用,则会比同步收集包装更快。

如果您只想从集合中删除元素,则可以使用Iterator而不是Iterable。

否则,你可以做的不是迭代原始集合,而是首先制作一个副本。 例如,如果你的集合是一个列表,那么你可以创build一个新的ArrayList(originaList)并迭代它。 应该对原始列表进行修改。

另一个可能更适合你的用例的select是,除了传统的for-each之外,不要使用for-each。