【问题标题】:ConcurrentMap inconsistenciesConcurrentMap 不一致
【发布时间】:2014-10-21 14:28:46
【问题描述】:

ConcurrentMap 的 JavaDoc - putIfAbsent 说:

  /**
    * If the specified key is not already associated
    * with a value, associate it with the given value.
    * This is equivalent to
    *
    * if (!map.containsKey(key))
    *     return map.put(key, value);
    * else
    *    return map.get(key);
    *  
    * except that the action is performed atomically.
    */  

但是 putIfAbsent(来自 ConcurrentMap)和 put(来自 Map)都返回前一个值(或者当没有前一个值时返回 null)。因此在示例中,当 map 不包含 key 时,返回 null。这是代码的正确意图吗?改为返回“值”不是更好吗?

【问题讨论】:

  • 你已经有价值了。

标签: java


【解决方案1】:

API 很可能是这样设计的,因此您可以区分以前没有映射(并且更新成功)和以前的映射存在但映射到完全相同的value 的情况。

问这是否比获取新值更实用并无济于事。我也偶然发现了这种行为。但 API 从 Java 5 开始就存在,以这种方式指定,并且不会更改。

附带说明一下,如果不存在先前的映射,Java 8 的 Map.computeIfAbsent 将返回计算值,从而表现得更像您的预期。

【讨论】:

  • 谢谢,我只是想证明 if (!map.containsKey(key)) return map.put(key, value);总是返回 false
  • Map.computeIfAbsent 很棒,因为你总是交出一个函数,它只在必要时执行昂贵的操作。
  • 对,Map.computeIfAbsent 是我从ConcurrentMap 的第一个版本开始就错过了...
【解决方案2】:

您已经(或应该)拥有新值。没有理由退回您刚刚插入的内容。

    ConcurrentMap<Integer, String> map = new ConcurrentHashMap<>();
    ...
    String newVal = "someString";
    String old = map.putIfAbsent(1, newVal);
    if(old == null){
        //no previous mapping
    }

【讨论】:

    猜你喜欢
    • 2018-01-02
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多