【问题标题】:How to replace HashMap Values while iterating over them in Java如何在 Java 中迭代 HashMap 值时替换它们
【发布时间】:2012-06-15 03:26:03
【问题描述】:

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

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

}

【问题讨论】:

    标签: java hashmap runnable


    【解决方案1】:

    使用 Java 8:

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

    使用 Java 7 或更早版本:

    您可以遍历条目并更新值,如下所示:

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

    【讨论】:

    • 我不敢相信我没有想到这一点。谢谢。
    • 实际上该模式有一个 FindBugs-Warning:低效使用 keySet 迭代器而不是 entrySet 迭代器 即使在大多数情况下并不重要,性能方面,在某些情况下,它可以产生巨大的影响。此外,我什至认为这两种情况下的代码都是清晰易读的。为什么要使用和发布一个明显有一些缺点而没有任何优点的模式? (即使缺点可以说很小)
    • @aioobe:我可以想象这对不同的地图实现有不同的影响,当然,但是有没有一种形式的迭代比后者更有效?因此 FindBugs-Warning 会是误报吗?但你是对的,我们不必在这里讨论。我猜你的回答还可以。
    • 您能解释一下为什么会这样吗?我记得,在使用 for each 循环对其进行迭代时,不允许更改集合的元素。
    • 您不得进行结构更改,例如添加或删除元素。
    【解决方案2】:

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

    在使用地图时,您有两个类似的更新选项,遍历Map 中的每个Map.Entry&lt;K,V&gt;,或者您可以遍历密钥SetMap 上有一些方法可以做这两件事。就个人而言,我会遍历每个Map.Entry&lt;K,V&gt;

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

    【讨论】:

      【解决方案3】:

      为什么不迭代 Map.Entry 对象?每个Entry 都会为您提供键和值,您无需在Map 上执行额外的get() 即可获得值。

      【讨论】:

        猜你喜欢
        • 2012-03-07
        • 1970-01-01
        • 2016-02-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-16
        • 2020-08-24
        • 1970-01-01
        相关资源
        最近更新 更多