在java*中将值放入映射中,而不存在*更新现有值(如果存在)

Dra*_*sha 9 java collections dictionary

我想做以下功能:

if (!map.contains(key)) {
  map.put(key, val);
}
Run Code Online (Sandbox Code Playgroud)

更新:让我们假设不是HashMap这样的地图被实现为某种树.

但请注意,它有点低效,因为如果我们进入实际上我们实际搜索地图两次.我其实喜欢这样做:

map.put_if_new_key(key, val);
Run Code Online (Sandbox Code Playgroud)

知道怎么用Java做到这一点?

Sig*_*ign 8

如果您希望在绝大多数情况下插入新元素.

ValType temp = map.put(key, val);
if(temp != null)
    map.put(key, temp);
Run Code Online (Sandbox Code Playgroud)

我认为这不是一个好主意,但是如果你可以充分理解你的用例,那么值得考虑.

如果您可以使用特定的地图实现而不仅仅是地图界面,那么您可以使用的第二个想法 NavigableMap

Map sub = map.subMap(key, true, key, true);
if (!sub.contains(key)) {
  sub.put(key, val);
}
Run Code Online (Sandbox Code Playgroud)

由于子树将是0或1个节点大,因此没有重复工作.

  • 关于第一种方法的一个警告:有两种情况可以返回null.密钥丢失,或密钥存在并与值null相关联.你无法分辨这种方法是什么. (2认同)

Mar*_*ers 5

如果你有一个ConcurrentMap<K, V>方法putIfAbsent

如果指定的键尚未与值关联,则将其与给定值关联。这相当于

if (!map.containsKey(key))
    return map.put(key, value);
else
    return map.get(key);
Run Code Online (Sandbox Code Playgroud)

除了动作是原子地执行的。

但是,该方法不存在于Map<K, V>.

  • 但是请注意 - 如果 OP 担心地图的两次查找略有增加,那么同步成本会差很多。 (3认同)
  • +1 表示(在代码中)此实现并不比 OP 提供的高效 (2认同)