gpt4 book ai didi

java - Hashmap.keySet()、foreach 和删除

转载 作者:太空狗 更新时间:2023-10-29 23:02:37 27 4
gpt4 key购买 nike

我知道使用 java 的“foreach”从列表中删除通常是一个大禁忌,应该使用 iterator.remove()。但是,如果我在 HashMap 的 keySet() 上循环,那么 remove() 是否安全?像这样:

for(String key : map.keySet()) {
Node n = map.get(key).optimize();
if(n == null) {
map.remove(key);
} else {
map.put(key, n);
}
}

最佳答案

编辑:

我没有注意到您并没有真正添加到 map 中——您只是在更改条目中的值。在这种情况下,pstanton 的 (pre-edit1) 解决方案几乎是正确的,但是您应该在迭代器返回的条目上调用 setValue,而不是调用 map.put。 (可能 map.put 会起作用,但我不相信这是有保证的——而文档指出 entry.setValue 工作。)

for (Iterator<Map.Entry<String, Node>> it = map.entrySet().iterator(); 
it.hasNext();)
{
Map.Entry<String, Node> entry = it.next();
Node n = entry.getValue().optimize();
if(n == null)
{
it.remove();
}
else
{
entry.setValue(n);
}
}

(遗憾的是 entry 没有 remove 方法,否则您仍然可以使用增强的 for 循环语法,使其不那么笨拙。)

旧答案

(我把它留在这里是为了更一般的情况,您只想进行任意修改。)

不——您既不应该添加到 map 也不应该直接从 map 中移除。 HashSet.keySet() 返回的集合是键的 View ,而不是快照。

可以通过迭代器删除,尽管这要求您显式使用迭代器而不是通过增强的 for 循环。

一个简单的选择是从原始集合创建一个新集合:

for (String key : new HashSet<String>(map.keySet())) {
...
}

在这一点上你很好,因为你没有对集合进行任何更改。

编辑:是的,您绝对可以通过键集迭代器删除元素。来自 HashMap.keySet() 的文档:

The set supports element removal, which removes the corresponding mapping from the map, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations. It does not support the add or addAll operations.

这甚至在 Map 接口(interface)本身中指定。


1 我决定编辑我的答案,而不仅仅是评论 psanton 的答案,因为我认为我为类似但不同的情况获得的额外信息非常有用,值得保留这个答案。

关于java - Hashmap.keySet()、foreach 和删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2026104/

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