gpt4 book ai didi

java - 我可以在迭代过程中使用keySet修改HashMap吗?

转载 作者:行者123 更新时间:2023-12-02 13:14:46 26 4
gpt4 key购买 nike

我知道在迭代期间不应修改集合。所以我们应该有解决方法。

我有一个代码:

Map<Key, Value> map = getMap(); // map generating is hidden
for (Key key : map.keySet()) {
if (isToRemove(key)) {
map.remove(key);
} else {
map.put(key, getNewValue());
}
}

这是未定义的行为还是有效的代码?

keySet 文档说映射的更改反射(reflect)在返回的集合中,反之亦然。这是否意味着以前的代码 Not Acceptable ?

最佳答案

answer from davidxxx正确 (+1) 指出 map 上的 View 集合链接到 map ,并且在迭代 View 集合时对 map 进行修改可能会导致 ConcurrentModificationException . map 上的 View 集合由entrySet提供。 , keySet ,和values方法。

因此,原始代码:

    Map<Key, Value> map = getMap();
for (Key key : map.keySet()) {
if (isToRemove(key)) {
map.remove(key);
} else {
map.add(key, getNewValue());
}
}

很可能会抛出 ConcurrentModificationException因为它会在每次迭代期间修改 map 。

如果 View 集合的迭代器支持remove,则可以在迭代 View 集合时从映射中删除条目。手术。 HashMap View 集合的迭代器确实支持这一点。 可以使用 setValue 设置特定映射条目(键值对)的值。方法Map.Entry迭代 map 时获得的实例 entrySet因此,可以在一次迭代中完成您想做的事情,而无需使用临时 map 。这是执行此操作的代码:

    Map<Key, Value> map = getMap();
for (var entryIterator = map.entrySet().iterator(); entryIterator.hasNext(); ) {
var entry = entryIterator.next();
if (isToRemove(entry.getKey())) {
entryIterator.remove();
} else {
entry.setValue(getNewValue());
}
}

注意Java 10的var的使用构造。如果您不是使用 Java 10,则必须显式写出类型声明:

    Map<Key, Value> map = getMap();
for (Iterator<Map.Entry<Key, Value>> entryIterator = map.entrySet().iterator(); entryIterator.hasNext(); ) {
Map.Entry<Key, Value> entry = entryIterator.next();
if (isToRemove(entry.getKey())) {
entryIterator.remove();
} else {
entry.setValue(getNewValue());
}
}

最后,考虑到这是一个中等复杂的映射操作,使用流来完成这项工作可能会很有成效。请注意,这会创建一个新 map ,而不是就地修改现有 map 。

    import java.util.Map.Entry;
import static java.util.Map.entry; // requires Java 9

Map<Key, Value> result =
getMap().entrySet().stream()
.filter(e -> ! isToRemove(e.getKey()))
.map(e -> entry(e.getKey(), getNewValue()))
.collect(toMap(Entry::getKey, Entry::getValue));

关于java - 我可以在迭代过程中使用keySet修改HashMap吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49688057/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com