如何在Java中迭代HashMap值时替换它们

Zac*_*ano 53 java hashmap runnable

我使用Runnable每秒从玩家冷却时间自动减去20,但我不知道如何在迭代它时替换值的值.如何让它更新每个键的值?

public class CoolDownTimer implements Runnable {
    @Override
    public void run() {
        for (Long l : playerCooldowns.values()) {
            l = l - 20;
            playerCooldowns.put(Key???, l);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

aio*_*obe 94

使用Java 8:

map.replaceAll((k, v) -> v - 20);
Run Code Online (Sandbox Code Playgroud)

使用Java 7或更早版本:

您可以迭代条目并更新值,如下所示:

for (Map.Entry<Key, Long> entry : playerCooldowns.entrySet()) {
    entry.setValue(entry.getValue() - 20);
}
Run Code Online (Sandbox Code Playgroud)

  • 实际上对于该模式存在一个FindBugs-Warning:_无效使用keySet迭代器而不是entrySet iterator_即使在大多数情况下无关紧要,但在性能方面,它在某些情况下会产生巨大的差异.此外,我甚至认为代码在两种情况下都清晰可读.为什么使用和发布一个显然有一些缺点而没有任何优势的模式?(即使缺点可以说很小) (4认同)
  • 您能解释一下为什么行得通吗?我记得,在使用for每个循环迭代它们时,不允许更改集合的元素。 (2认同)
  • 您不允许进行*结构*更改,例如添加或删除元素。 (2认同)

Jon*_*Jon 26

好吧,你不能通过迭代Map(正如你现在正在做的)中的值集来做到这一点,因为如果你这样做那么你没有引用键,如果你没有引用键,那么您无法更新地图中的条目,因为您无法找到与刚刚更新的值相关联的键.

当使用地图时,您有这样的更新两种选择,通过每个迭代Map.Entry<K,V>Map,或者您也可以通过按键进行迭代Set.有两种方法Map可以做这两件事.就个人而言,我会遍历每一个Map.Entry<K,V>.

for (Map.Entry<String, Long> entry : playerCooldowns.entrySet()) {
    entry.setValue(entry.getValue() - 20);
}
Run Code Online (Sandbox Code Playgroud)


Bri*_*new 10

为什么不迭代Map.Entry对象?每个Entry都会为您提供密钥和价值,您无需为了获得价值而执行额外get()的操作Map.