【问题标题】:How to remove a value mapped to a key when a key has multiple values mapped to it in a concurrent hash map?当一个键在并发哈希映射中有多个映射到它的值时,如何删除映射到一个键的值?
【发布时间】:2021-11-02 20:36:50
【问题描述】:

我是并发哈希映射的新手,我想知道是否可以获得有关 .remove(key) 方法的一些指导。

如果我有一个具有 1 个键但有多个映射到该键的值的并发哈希映射,我该如何删除与该键关联的该值但不删除该键和与该键关联的其他值?

如果我有类似的东西:

ConcurrentHashMap<String, List<String>> userValues = new ConcurrentHashMap<>();
   userValues.computeIfAbsent(user, key -> new ArrayList<>()).add(value1);
   userValues.computeIfAbsent(user, key -> new ArrayList<>()).add(value2);
   userValues.computeIfAbsent(user, key -> new ArrayList<>()).add(value3);
   userValues.computeIfAbsent(user, key -> new ArrayList<>()).add(value4);

然后我打印出我的地图,我得到如下输出:

{user=[value1, value2, value3, value4]}

我想按照userValues.remove(value1) 的方式做一些事情,以获得{user=[value2, value3, value4]} 的新输出

如何在上面的代码中正确且线程安全地执行我想要的操作?

【问题讨论】:

  • 在任何映射中,每个键都与一个且只有一个值对象相关联。值对象本身可以是集合或复合,或两者兼而有之。
  • userValues.get(key).remove(value1),因为您想从与密钥关联的列表中删除 value1

标签: java concurrenthashmap


【解决方案1】:

使用ArrayList 不是线程安全的。可以将映射功能切换为key -&gt; Collections.synchronizedList(new ArrayList&lt;&gt;())

ConcurrentHashMap<String, List<String>> userValues = new ConcurrentHashMap<>();
Function<? super String, ? extends List<String>> mappingFunction = key -> Collections.synchronizedList(new ArrayList<>());

userValues.computeIfAbsent(user, mappingFunction).add(value1);
userValues.computeIfAbsent(user, mappingFunction).add(value2);
userValues.computeIfAbsent(user, mappingFunction).add(value3);
userValues.computeIfAbsent(user, mappingFunction).add(value4);

userValues.get(user).remove(value3);
=>
userValues ==> {user=[value1, value2, value4]}

您可以考虑其他线程安全的 List 实现,例如 CopyOnWriteArrayList

【讨论】:

    【解决方案2】:

    以下是线程安全的,虽然丑陋。 检查 ConcurrentHashMap.computeIfPresentcompute 的 javadocs!

       userValues.compute(user, (k, v) -> {
         if (v == null) v = new ArrayList<>();
         v.add(value1);
         return v;})
    
       userValues.computeIfPresent(user, (k, v) -> {v.remove(value1); return v;})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-13
      • 2013-03-12
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多