Java HashMap在迭代时添加新条目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27753184/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:19:49  来源:igfitidea点击:

Java HashMap add new entry while iterating

javaiteratorconcurrentmodification

提问by Buru

In a HashMap

在 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

}

When i trying to add a new entry to map it throws ConcurrentModificationException. For remove and update iterator has safely removing methods. How to add new entry while iterating?

当我尝试添加一个新条目来映射时,它抛出ConcurrentModificationException. 对于删除和更新迭代器具有安全删除方法。如何在迭代时添加新条目?

回答by Dunes

You need to consider what it means to put a value to a Map whilst iterating. HashMap defines no order over which its entries will be iterated over. So when you put a new entry, should the entry be returned by the iterator later or not. Consistency of behaviour is important. However, whichever way you decide you'll get inconsistent behaviour when you put a new value to a preexisting key. If the key has already been iterated over then the change won't appear and will appear if the key has yet to be produced by the iterator.

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

A simple way to overcome this problem is to create a temporary Map of the new key-value pairs and add the temporary Map to the main Map at the end of your iteration.

解决这个问题的一个简单方法是为新的键值对创建一个临时 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);

回答by Juned Ahsan

You need to use ConcurrentHashMapto add elements while iterating the collection. HashMap uses fail-fast iterator, which throws ConcurrentModificationException when the collection is updated while iterating. Whereas ConcurrentHashMapuses fail-safe iterator, which basically works on the clone of the underlying collection and hence allows modification while iterating.

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

回答by john16384

How about:

怎么样:

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

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

I checked the HashMap implementation, it does not change its modification count when updating an entry like this. I also see no reason why this shouldn't be allowed. Nothing is removed, nothing is added and no keys are changed.

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

回答by Bogdan Alexandru

What I did was to create an array with the current elements and then iterate through the array:

我所做的是用当前元素创建一个数组,然后遍历该数组:

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

for (Feature feature : initialFeatures)
{/* Code that can safely add to the featureMap */}