我有一个CuncurrentHasMap:
private static ConcurrentHashMap<String, Object> testParameters =
new ConcurrentHashMap<String, Object>();
我(有时)使用相同的键推入对象,这些对象是TreeMap(string,MyPrivateClass)类型的TreeMap。
如何更改此put方法,以便将具有相同键的对象放在一起而不被覆盖?
public static void put(String key, Object object) {
getTestParameters().put(key, object);
}
答案 0 :(得分:5)
使用值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;
});
答案 1 :(得分:0)
如果您可以接受,则可以使用Guava Multimap
的实现。它可以为单个键存储多个值。由于看起来您需要一个线程安全的Map,因此我将使用Multimaps.synchronizedMultimap method并执行以下操作:
Multimap<String, Object> multimap = HashMultimap.create();
Multimap synchronizedMultimap = Multimaps.synchronizedMultimap(multimap);
答案 2 :(得分:0)
正如您在评论中所述,应将新的TreeMap
类型值与现有值合并,您可以像这样重写字段和put
方法:
private static Map<String, Map<String, MyPrivateClass>> testParameters = new ConcurrentHashMap<>();
public static void put(String key, TreeMap<String, MyPrivateClass> value) {
Map<String, MyPrivateClass> currentValue = testParameters.get(key);
if(null == currentValue) {
// create new sub map
TreeMap<String, MyPrivateClass> newValue = new TreeMap<>(value);
testParameters.put(key, Collections.synchronizedMap(newValue));
} else {
// merge values' entries into existing sub map.
currentValue.putAll(value);
}
}
可以写得更短:
public static void put(String key, TreeMap<String, MyPrivateClass> value) {
testParameters.computeIfAbsent(key, k -> (
Collections.synchronizedMap(
new TreeMap<>(value.comparator())))).putAll(value);
}
使用ConcurrentHashMap表示您将从多个线程同时访问地图,这就是为什么我添加了Collections.synchronizedMap()
。