这个问题在这里已经有答案了:
遍历集合,在移除循环中的对象时避免concurrentmodificationexception(27个答案)
三年前关门了。
我在做:
for (Object key : map.keySet())
if (something)
map.remove(key);
引发了concurrentmodificationexception,所以我将其更改为:
for (Object key : new ArrayList<Object>(map.keySet()))
if (something)
map.remove(key);
此过程以及修改Map的任何其他过程都在同步块中。
有更好的解决办法吗?
如果没有人能想出更好的解决办法,首先说“不”会让你感到高兴;)
12条答案
按热度按时间wj8zmpe11#
使用真正的迭代器。
实际上,您可能需要在
entrySet()
而不是keySet()
为了让它工作。ukqbszuj2#
concurrenthashmap
你可以用
java.util.concurrent.ConcurrentHashMap
.它实现了
ConcurrentMap
(扩展了Map
接口)。例如。:
这种方法使代码保持不变。只有
map
类型不同。pxyaymoc3#
有更好的解决办法吗?
当然,在一个语句中有更好的方法,但这取决于基于哪些元素被移除的条件。
例如:去掉那些
value
是测试,则使用以下方法:在Java8中,可以使用lambda表达式在一行中更新它。
我知道这个问题太老了,但是更新更好的方法并没有什么坏处:)
1szpjjfi4#
你必须使用
Iterator
在遍历Map时安全地删除元素。vsmadaxz5#
cnjp1d6j6#
我同意保罗汤姆布林的观点。我通常使用键集的迭代器,然后根据该键的值设置条件:
q5lcpyga7#
这也应该管用。。
pokxtpni8#
也许您可以在Map上迭代,寻找要删除的键,并将它们存储在一个单独的集合中。然后从Map中删除密钥集合。通常不赞成在迭代时修改Map。如果Map很大,这个想法可能会受到怀疑。
5hcedyr09#
Java8支持更具声明性的迭代方法,因为我们指定了我们想要的结果,而不是如何计算它。新方法的好处是可读性更强,不易出错。
结果如下:
z2acfund10#
对于java 8,您可以按以下方式执行:
oracle文档:
entrySet()
集合由Map支持,因此对Map的更改将反映在集合中,反之亦然qzwqbdag11#
另一种更冗长的方式
mbskvtky12#
下面是一个代码示例,用于在for循环中使用迭代器删除条目。