[英]ConcurrentHashMap - adding items with the same Key
I have a CuncurrentHasMap: 我有一个CuncurrentHasMap:
private static ConcurrentHashMap<String, Object> testParameters =
new ConcurrentHashMap<String, Object>();
I am pushing (sometimes) objects with the same keys, those objects are TreeMaps of type TreeMap(string, MyPrivateClass). 我用相同的键推送(有时)对象,这些对象是TreeMap(string,MyPrivateClass)类型的TreeMap。
How to change this put method, so that objects with same key will be placed together and not be overridden? 如何更改此放置方法,以使具有相同键的对象放在一起而不被覆盖?
public static void put(String key, Object object) {
getTestParameters().put(key, object);
}
Make the value List<Object>
(or some other container/collection type), instead of Object
: 使值
List<Object>
(或其他一些容器/集合类型),而不是Object
:
private static ConcurrentHashMap<String, List<Object>> testParameters =
new ConcurrentHashMap<>();
and then use compute
instead of put
to create and add to the list: 然后使用
compute
而不是put
来创建并添加到列表中:
getTestParameters().compute(key, (k, v) -> {
if (v == null) v = new ArrayList<>();
v.add(object);
return v;
});
If this is acceptable to you, you could use an implementation of Guava Multimap
. 如果您可以接受,则可以使用Guava
Multimap
的实现。 It can stores multiple values for a single key. 它可以为单个键存储多个值。 Since it looks like you need a Map which is thread-safe, I would use the Multimaps.synchronizedMultimap method and do something like this:
由于看起来您需要一个线程安全的Map,因此我将使用Multimaps.synchronizedMultimap方法并执行以下操作:
Multimap<String, Object> multimap = HashMultimap.create();
Multimap synchronizedMultimap = Multimaps.synchronizedMultimap(multimap);
As you stated in comments that new TreeMap
typed values should be merged with existing ones, you can rewrite your field and put
method like this: 正如您在评论中所述,应将新的
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;
}
);
}
The use of ConcurrentHashMap indicates that you are going to access the map concurrently from multiple threads, this is why I added Collections.synchronizedMap()
as you likely also want to perform reads concurrently on the resulting TreeMaps. 使用ConcurrentHashMap表示您将从多个线程同时访问地图,这就是为什么我添加
Collections.synchronizedMap()
因为您可能还希望同时对结果TreeMap执行读取。
Update: While still maintaining the TreeMaps' entries, I switched from computeIfAbsent
to compute
as AndyTurner does in his answer because my former approach was not atomic. 更新:在仍然维护TreeMaps条目的同时,我像AndyTurner在他的回答中那样,从
computeIfAbsent
切换到了compute
,因为我以前的方法不是原子方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.