В разрабатываемом приложении я использую несколько карт, связывающих строки с коллекциями элементов, например, Map<String, List<String>>
, Map<String, SortedSet<Object>>
.Во многих случаях я хочу, чтобы простые функции добавляли / удаляли элементы в коллекции, заданной определенным ключом, возможно, удаляя или создавая новые записи на карте.
Я реализовал несколько общих методов для эффекта, но putIntoCollection()
метод дает мне некоторые проблемы.Моя реализация, которая не вызывает никаких предупреждений, выглядит следующим образом:
public static <K, V, C extends Collection<V>> void putIntoCollection(
Map<K, C> map, K key, V value, Class<? extends C> collectionClass)
throws InstantiationException, IllegalAccessException {
C collection = map.get(key);
if (collection == null) {
collection = collectionClass.newInstance();
map.put(key, collection);
}
collection.add(value);
}
C
представляет тип коллекции, который может быть любым типом Collection
, а параметр Class<? extends C>
позволяетпередать конкретный токен класса для создания новых C
(например, передать токен ArrayList
для карты Lists
).
Однако, если я попытаюсь использовать его следующим образом:
Map<String, Set<String>> tags;
String key, value;
MapUtilities.putIntoCollection(map, key, value, HashSet.class);
Я получаю ошибку компиляции:
The parameterized method <K, V, Set<V>>putIntoCollection(Map<K,Set<V>>, K, V, Class<? extends Set<V>>) of type MapUtilities is not applicable for the arguments (Map<K,Set<V>>, K, V, Class<HashSet>)
Я понимаю, что это происходит, потому что я передаю аргумент Class<HashSet>
, в то время как он ожидает параметризованный класс Set.Однако я не знаю, как (или если) я могу получить такие случаи Class
.Есть ли лучший способ сделать общий метод, такой как этот?