Java HashMap在迭代时增加新条目

问题描述 投票:11回答:4

在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. 对于删除和更新迭代器有安全的删除方法。如何在迭代时添加新条目?

java iterator concurrentmodification
4个回答
10
投票

你需要考虑在迭代时将一个值放到一个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);

3
投票

你需要使用 ConcurrentHashMap 来在迭代集合的同时添加元素.HashMap使用fail-fast迭代器,当迭代集合时,它会抛出ConcurrentModificationException。HashMap使用fast-fast迭代器,当集合在迭代时被更新时,它会抛出ConcurrentModificationException。而 ConcurrentHashMap 使用故障安全迭代器,它基本上是在底层集合的克隆上工作,因此允许在迭代时进行修改。


2
投票

怎么样。

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

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

我检查了HashMap的实现, 它不会在更新一个条目时改变它的修改次数,就像这样。 我也看不出有什么理由不允许这样做。 没有删除任何东西,没有增加任何东西,也没有改变键。


0
投票

我所做的是用当前元素创建一个数组,然后在数组中迭代。

Feature[] initialFeatures = featureMap.values().toArray(new Feature[featureMap.values().size()]);

for (Feature feature : initialFeatures)
{/* Code that can safely add to the featureMap */}
© www.soinside.com 2019 - 2024. All rights reserved.