- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我知道使用 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/
这是一个假设性问题。如果我有来自 3 个单独的 sql db 查询的 3 个数组,这些查询都与另一个数组相关。例如…… //db schools id | school_name classes id
在我的应用程序中,我使用 scrape(string url) 方法从网页中抓取链接。可以说它每次都返回我 10 个 url。 我想从每个抓取的 url 中抓取 10 个链接。 长话短说: (第 1
我的java7代码: final Map result = new HashMap<>(); final Set> classes = getClasses(co.glue()); for (fina
是否可以在 SwiftUI 中设置变量,例如在这样的 ForEach 中: struct ContentView: View { var test: Int var body: som
在 D、int、uint 中使用 foreach 时,循环索引的首选类型是什么?或者只是通过省略类型自动实现? 最佳答案 一般来说,索引应该是size_t。与长度相同。如果您尝试使用 int 或 ui
根据 http://dlang.org/statement.html 的“Foreach 限制”部分以下代码 int[] a; int[] b; foreach (int i; a) { a
在什么情况下我们应该在 JDK 8 中使用旧的 foreach 循环遍历新的 collection.forEach() 还是最好的做法是转换 every foreach 循环?是否存在任何重要的性能差
获得类似东西的惯用方法是什么? ((fn [coll] (function-body)) [:a :b :c :d]) -> [[:a :b][:a :c][:a :d][:b :c][:b :d][
我正在创建一个基于 who is it? 的 Java 应用程序。现在我正在制作一种方法,在回答问题时我需要其他卡片。 我有两个列表: 列表是一个 ImageView 列表,其中我有卡片必须代表的 2
我希望有人能在我发疯之前帮助我。 我有 3 张 table : Table A SELECT companypk, companyname, logo, msscope FROM global_com
我正在尝试将多个字符串添加到 C# 中的 MailAddress。 如果我使用ForEach,我的代码会是这样 foreach (var item in GetPeopleList()
我没有太多的 C# 经验,所以如果有人能指出正确的方向,我将不胜感激。我有一个引用对象变量的 foreach 循环。我希望在主循环中创建另一个 foreach 循环,将当前变量与对象数组中的其余变量进
下面的代码每 60 秒删除文件夹“Images”中的文件,它可以工作,但是当文件夹为空时它会显示:警告:为 foreach() 提供的参数无效如果没有文件,如何解决这个问题,说“文件夹为空而不是那个警
我需要在两种不同的模式下运行,因此“if”(第二个稍后构建一个大的 csv) 下面对于单个实例运行正常,但在第二个 (*) 的加载时间上失败,因为在前 7k 行中的每一行上运行。 我想避免可怕的事情
我们可以使用以下两种方法实现类数组对象的迭代: let arrayLike = document.getElementsByClassName('dummy'); [].forEach.call(ar
我有这个代码 ... 它说: Attribute value invalid for tag forEach according to TLD 最佳答案 forEach标签不支持 valu
我在 SwiftUI 中有一个像这样的 ForEach: ForEach(entries) { (e: MyType) in NavigationLinkItem(entry: e) } 现在我
我无法在一个 Foreach 或 Foreach-Object 循环中使用多个命令 我的情况是—— 我有很多文本文件,大约 100 个。 所以他们被阅读 Get-ChildItem $FilePath
我必须从 json 文件(实际上是 2 个 json 文件)执行 ForEach,因此我执行 2 forEach,代码是 table { font-family: arial, sans-
我对编程很陌生,当我执行 forEach 函数时,我的应用程序返回错误。我的controller.js中有以下代码 $scope.ajaxRequest = A.Game.get({action: '
我是一名优秀的程序员,十分优秀!