【问题标题】:ConcurrentHashMap: how to replace the value of an entry only if the current value is smalleConcurrentHashMap:仅当当前值较小时如何替换条目的值
【发布时间】:2016-07-20 05:59:00
【问题描述】:

我想:

  1. 在 ConcurrentHashMap 中添加一个条目,如果该键没有条目,或者
  2. 仅当当前值较小时才替换键的值。

我想出了下面的代码,但它确实有 while (true),它看起来对我来说很可怕 :)

我想和你们一起检查一下。你认为它有效吗?

// Input: map, k, t
while (true) {
    if (map.containsKey(k)) {
        current = map.get(k);
        if (current != null && current < t) {
            if (map.replace(k, current, t))
                break;
        } else if (current != null && current >= t) {
            break;
        }
    } else {
        pre = map.putIfAbsent(k, t);
        if (pre == null)
            break;
    }
}

【问题讨论】:

  • 你试过了吗?您是否在您的 IDE 调试器中运行它并一次通过它一行?请这样做,这将比有人告诉你更具教育意义。顺便说一句,根本不需要while(true)(或任何类型的循环)。
  • 使用Map.entrySet()进行迭代
  • @JimGarrison 为什么我不需要 while (true)?假设一个线程想要写 t,但是 map 已经有了 key,所以它去第一个 If。然后在替换时,replace返回false,因为同时该值已被另一个线程更改为高于current但小于t的值。由于线程“想要”写入 t(因为 t 更高),它需要重新开始。

标签: java hashmap


【解决方案1】:

如果您使用的是 Java 8,则可以使用 merge 方法。需要:

  • 要映射到的键 K
  • 如果 K 处还没有值,则使用值 V
  • BiFunction&lt;K,K,V&gt;F 将任何已经存在的值与 V 结合起来,并将其存储在 K 中

对于您的用例,您将:

  • K:你的钥匙
  • V:新值
  • F:比较其两个输入并返回两者中较高者的函数

如果 K 处还没有值,它只会存储 V。否则,它会将新 V 和旧 V 传递给您的函数,并将结果存储在 K 中。由于您的函数返回较高的值在两者中,这相当于替换该值,当且仅当它高于先前的值时。

【讨论】:

  • OP 使用的是 Java 8 中添加的replace(),所以 OP 使用的是 Java 8。
  • 谢谢,我会尝试使用这个方法。顺便说一句,我分配的值更高而不是更小。
  • @MohammadRoohitavaf 它应该是传递给该 BiFunction 的参数之一。这不工作吗?
  • 是的,这是第一个参数,谢谢^_^。我希望我们有类似的删除方法。我也需要那个。我发现有一个 remove 函数,它只在当前值等于预期值时才删除,但如果当前值小于新值,我们没有任何 remove 函数。
猜你喜欢
  • 2021-11-27
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-23
  • 1970-01-01
相关资源
最近更新 更多