繁体   English   中英

ConcurrentHashMap-添加具有相同Key的项目

[英]ConcurrentHashMap - adding items with the same Key

我有一个CuncurrentHasMap:

private static ConcurrentHashMap<String, Object> testParameters =
new ConcurrentHashMap<String, Object>();

我用相同的键推送(有时)对象,这些对象是TreeMap(string,MyPrivateClass)类型的TreeMap。

如何更改此放置方法,以使具有相同键的对象放在一起而不被覆盖?

public static void put(String key, Object object) {

        getTestParameters().put(key, object);
}

使值List<Object> (或其他一些容器/集合类型),而不是Object

private static ConcurrentHashMap<String, List<Object>> testParameters =
    new ConcurrentHashMap<>();

然后使用compute而不是put来创建并添加到列表中:

getTestParameters().compute(key, (k, v) -> {
  if (v == null) v = new ArrayList<>();
  v.add(object);
  return v;
});

如果您可以接受,则可以使用Guava Multimap的实现。 它可以为单个键存储多个值。 由于看起来您需要一个线程安全的Map,因此我将使用Multimaps.synchronizedMultimap方法并执行以下操作:

Multimap<String, Object> multimap = HashMultimap.create();
Multimap synchronizedMultimap = Multimaps.synchronizedMultimap(multimap);

正如您在评论中所述,应将新的TreeMap类型值与现有值合并 ,您可以重写字段并put方法,如下所示:

private static final Map<String, Map<String, MyPrivateClass>> testParameters = new ConcurrentHashMap<>();

public static void put(String key, TreeMap<String, MyPrivateClass> value) {
    testParameters.compute(key, (k,v) -> {
            if(null == v) {
                v = Collections.synchronizedMap(new TreeMap<>(value.comparator()));
            }
            v.putAll(value);
            return v;
        }
    );
}

使用ConcurrentHashMap表示您将从多个线程同时访问地图,这就是为什么我添加Collections.synchronizedMap()因为您可能还希望同时对结果TreeMap执行读取。

更新:在仍然维护TreeMaps条目的同时,我像AndyTurner在他的回答中那样,从computeIfAbsent切换到了compute ,因为我以前的方法不是原子方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM