遍历/更新HashMap

6

我知道有几种遍历哈希表的方法,但在遍历时修改哈希表,有什么好的方法(除了创建一个新的哈希表并且去掉旧的哈希表)?

我想要像下面这样:

for (Map.Entry<String, Integer> entry : wordcounts.entrySet()) {
    String key = entry.getKey();
    Integer value = entry.getValue();
    if(blacklist.contains(key))
        //remove key/value for that key from wordcounts
    if(mappings.contains(key))
     //change key in wordcounts from one string to another based on the key's value in a <string,string> map (mappings)
}

我能在遍历地图的过程中修改它吗?我必须使用迭代器吗?


你可以使用 Iterator 在遍历时删除条目。如果要更改键值,则需要创建一个新的 Map,并复制不变的值或修改并插入更改的值。如果在添加到新 Map 时从旧的 Map 中删除它们,则时间和内存成本并不太大。 - Lee Meador
好的,我会在一个小地图上进行这些特定的修改,这样创建一个新地图可能会更简单。 - LemonMan
@LeeMeador 我确实仔细阅读了这篇文章,虽然它指定了如何删除元素,而不是修改键,但如果我只是创建一个新的映射,那应该不是问题。 - LemonMan
我可能最终需要使用迭代器来删除长度低于某个特定值的单词。 - LemonMan
3个回答

3
利用地图:先查看您的其他集合并执行操作。
for(String blacklisted : blacklist) {
    wordcounts.remove(blacklisted);
}
for(String mapping : mappings) {
    String oldKey =    // get old key
    String value = wordcounts.get(oldKey);
    wordcounts.remove(oldKey);
    wordcounts.put(mapping, value);
}

第一部分很聪明,可以让事情更快。但对于第二部分,它会修改键或值吗?因为我想修改键。 - LemonMan
对于第二个,您可以将其删除,然后修改后再添加回来。 - Lee Meador
很好,鉴于我正在处理小地图,成本可能不会太高。 - LemonMan

1
使用 Map.Entry.setValue 来更改映射的值。如果您想要删除映射,使用 setValue(null) 使用一个 Iterator

转念一想,使用 setValue(null) 可能不会删除映射。我会测试一下并回复你。 - Jeffrey
是的,浏览Javadocs看起来可能只是将值设置为null。 - LemonMan
(虽然我认为有一个map.remove(key)选项) - LemonMan
@Lemonio 是的,setValue(null) 只是将映射设置为 null。如果您在迭代时尝试使用 Map.remove(key),则会收到 ConcurrentModificaitonException - Jeffrey
是的,这正是我从其他帖子中所想到的,但vakh的建议似乎是一个不错的去除方法。 - LemonMan

0

不要在迭代过程中尝试删除项目,否则您将从迭代器中得到一个异常。最好的方法是:

a)通过迭代/复制到新地图来克隆地图,或者 b)在进行迭代时跟踪要删除的项目,并在完成迭代后删除它们。

如果您正在更改键,则同样适用相同的方法..在进行迭代时跟踪并在完成迭代后进行删除/添加。

如果您只是更改值,请直接进行更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接