Я настоятельно рекомендую использовать для этого библиотеки Google Guava , в частности реализацию Multimap . HashMultimap будет вашим лучшим выбором, хотя, если вам нужны параллельные обновления, вам нужно будет обернуть его в делегате, используя Multimaps.synchronizedSetMultimap () .
Другой вариант - использовать ComputingMap
(также из Гуавы), который представляет собой карту, которая, если значение, возвращаемое при вызове get(Key)
, не существует, то оно создается там и тогда. ComputingMap
s создаются с использованием MapMaker .
Код из вашего вопроса будет примерно:
ConcurrentMap<KEYTYPE, Set<VALUETYPE>> hashMap = new MapMaker()
.makeComputingMap(
new Function<KEYTYPE, VALUETYPE>() {
public Graph apply(KEYTYPE key) {
return new HashSet<VALUETYPE>();
}
});
Function
будет вызываться только тогда, когда вызов get()
для определенного ключа в противном случае вернет ноль. Это означает, что вы можете сделать это:
hashMap.get(key).put(value);
безопасно зная, что HashSet<VALUETYPE>
создан, если он еще не существует.
MapMaker
также имеет значение, поскольку он дает вам контроль над настройкой возвращаемой Карты, позволяя вам указать, например, уровень параллелизма, используя метод concurrencyLevel()
. Вы можете найти это полезным:
Управляет разрешенным параллелизмом между операциями обновления. Используется как подсказка для внутренней проклейки. Таблица внутренне разделена, чтобы попытаться разрешить указанное количество одновременных обновлений без конфликта. Поскольку назначение записей этим разделам не обязательно является единообразным, фактический наблюдаемый параллелизм может отличаться.