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

如何在Java中迭代HashMap值时替换它们,java,hashmap,runnable,Java,Hashmap,Runnable,我使用Runnable每秒自动从玩家的冷却时间中减去20,但我不知道如何在迭代过程中替换某个值。如何让它更新每个键的值 public class CoolDownTimer implements Runnable { @Override public void run() { for (Long l : playerCooldowns.values()) { l = l - 20; playerCooldowns.p

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

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

}

为什么不迭代对象呢?每个
条目将为您提供键和值,您不必在
映射上执行额外的
get()
来获取值。

使用Java 8:

map.replaceAll((k, v) -> v - 20);

使用Java 7或更早版本:

map.replaceAll((k, v) -> v - 20);
您可以按如下方式迭代条目并更新值:

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

好吧,你不能通过迭代
映射中的一组值来实现(就像你现在所做的那样),因为如果你这样做,那么你就没有对键的引用,如果你没有对键的引用,那么你就无法更新映射中的条目,因为您无法找出哪个键与刚刚更新的值关联

使用地图时,您有两个类似这样的更新选项:迭代每个
地图。在
地图中输入
,或者您可以迭代键
设置
Map
上有两种方法来完成这两件事。就个人而言,我会遍历每个
Map.Entry

for(Map.Entry:playerCooldowns.entrySet()){
entry.setValue(entry.getValue()-20);
}

我真不敢相信我没有想到这一点。谢谢。事实上,对于这种模式有一个FindBugs警告:键集迭代器而不是entrySet迭代器的使用效率低下,即使在大多数情况下这并不重要,但从性能角度来看,在某些情况下,它可能会产生巨大的差异。此外,我甚至认为代码在这两种情况下都是清晰可读的。为什么要使用和发布一个明显有一些缺点而没有任何优点的模式?(即使缺点可以说很小)@aioobe:我可以想象,这对不同的map实现有不同的影响,当然,但是是否有一种形式的迭代比后者更有效?因此FindBugs警告是假阳性?但你是对的,我们不必在这里讨论这个问题。我想你的答案还是可以的。你能解释一下为什么这样做吗?我记得,在使用for-each循环对集合进行迭代时,不允许更改集合的元素,也不允许进行结构更改,例如添加或删除元素。