Java HashMap在迭代时添加新条目

时间:2015-01-03 08:52:51

标签: java iterator concurrentmodification

在HashMap中

map = new HashMap<String,String>();

it = map.entrySet().iterator();
while (it.hasNext())
{
    entry = it.next();
    it.remove(); //safely remove a entry
    entry.setValue("new value"); //safely update current value
    //how to put new entry set inside this map
    //map.put(s1,s2); it throws a concurrent access exception

}

当我尝试添加新条目以进行映射时,它会抛出ConcurrentModificationException。对于删除和更新,迭代器已安全地删除方法。如何在迭代时添加新条目?

3 个答案:

答案 0 :(得分:7)

您需要考虑在迭代时为Map添​​加值意味着什么。 HashMap没有定义其条目将被迭代的顺序。因此,当您放入一个新条目时,迭代器是否应该稍后返回该条目。行为的一致性很重要。但是,当您将新值添加到预先存在的键时,无论您决定采用哪种方式都会产生不一致的行为。如果密钥已经迭代过,则更改将不会出现,并且如果迭代器尚未生成密钥,则会出现更改。

解决此问题的一种简单方法是创建新键值对的临时Map,并在迭代结束时将临时Map添加到主Map。

Map<String,String> values = ...

Map<String,String> temp = new HashMap<>();
for (Entry<String,String> entry : values.entrySet()) {
    if ("some value".equals(entry.getValue()) {
        temp.put(entry.getValue(), "another value");
    }
}
values.putAll(temp);

答案 1 :(得分:2)

在迭代集合时,您需要使用ConcurrentHashMap添加元素。 HashMap使用fail-fast迭代器,在迭代时更新集合时抛出ConcurrentModificationException。而ConcurrentHashMap使用故障安全迭代器,它基本上用于克隆底层集合,因此允许在迭代时进行修改。

答案 2 :(得分:1)

怎么样:

map = new HashMap<String,String>();

it = map.entrySet().iterator();
while (it.hasNext())
{
    entry = it.next();
    entry.setValue("new value"); // update current value
}

我检查了HashMap实现,在更新这样的条目时,它不会更改其修改计数。我也没有理由不允许这样做。没有删除,没有添加任何内容,也没有更改密钥。