【发布时间】:2016-11-08 15:45:15
【问题描述】:
假设我做了类似的事情:
for (X x : some_map.values ())
doSomething (x);
其中doSomething() 间接通过几层代码为some_map 添加了更多值。使用迭代器(如上面的示例代码),我得到了ConcurrentModificationException。
我可以将some_map 设为LinkedHashMap,即具有可预测的迭代顺序。此外,当向其中添加新项目时,它总是在迭代顺序结束时添加。换句话说,如果ConcurrentModificationException 以某种方式没有 被抛出,则循环只会在最后遍历新添加的项目,即可以正常工作。或者,换一种说法,我确实有这里有一个并发修改,但我可以保证它的行为是明确定义的,没有错误。
问题:我可以在上述循环中使用与迭代器“相似”的东西来避免并发修改异常吗?
请注意,由于一些额外的限制,我无法指出添加项目时知道循环。我也无法将其更改为不是地图的东西。这只是一段代码,但some_map 也在其他地方使用,是一个地图是有原因的。
编辑:
我的问题是我是否可以迭代(不一定以标准方式)我添加项目的同一张地图。很明显,我可以改为迭代副本,在循环将所述副本与原始副本进行比较以找到新项目后,迭代这些项目等等。问题是,我可以完全避免这种情况,因为在我的情况下,唯一的问题是过度急切地抛出 ConcurrentModificationException。回答“不,你不能”对我来说比“你可以做......而不是”更好,因为我可以自己为此设计一个替代代码。我只是想知道我是否忽略了一些优雅的解决方案。
【问题讨论】:
-
您可以跟踪应该添加哪些元素,然后在这些元素上重新运行该函数,直到没有更多元素要添加。完成所有迭代后,您可以按顺序添加所有新元素。
-
如果同时添加了一个新值,如果同时迭代这些值,您希望能够直接看到它吗?
-
@marstran:这不是一个选项,因为添加项目的地方对循环一无所知,因此不能有任何解决方法(比如添加到其他集合)。
-
澄清一下:如果
doSomething()向地图添加了一个条目,您是否希望您的循环也针对该值进行迭代?即你希望你的迭代“看到”你的地图的变化。如果是这样,如何修改条目的值和删除?
标签: java concurrentmodification