【发布时间】:2017-11-20 06:08:26
【问题描述】:
我正在使用身份哈希映射来跟踪我之前在自定义序列化程序中看到的对象。我有一个 while 循环,我尝试在其中迭代地图中的条目。在方法调用addAllFields 期间,可能会将对象添加到映射的键集中。经过一些调试后,我注意到我的iterator.hasNext() 返回false,即使我知道自上次循环体执行以来对象已添加到地图中。我在这里做错了什么?
public Document serialize(Object obj) throws Exception {
reset();
addToMap(obj);
Set<Object> keys = map.keySet();
Iterator<Object> iterator = keys.iterator();
while(iterator.hasNext()) {
Object key = iterator.next();
Element objectElement = createObjectElement(key.getClass().getName(), map.get(key));
addAllFields(objectElement, key);
document.getRootElement().addContent(objectElement);
}
return document;
}
【问题讨论】:
-
“我在这里做错了什么?” 在迭代时修改地图。
keySet()的 Javadoc 说:如果在对集合进行迭代时修改了地图,则迭代的结果是未定义。 -
是否还有另一个您知道的没有这种未定义行为的哈希映射?
-
ConcurrentHashMap。keySet()的 Javadoc 说:视图的迭代器和拆分器是 weakly consistent,即保证遍历元素,因为它们在构造时恰好存在一次,并且可能(但不保证)反映后续的任何修改施工。