java-管理集合图的通用方法

提问

在我正在开发的应用程序中,我利用了一些将字符串与元素集合相关联的映射,例如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代表集合的类型,它可以是任何类型的集合,并且类&lt ;?扩展C>参数使我可以传递具体的类令牌来实例化新的C(例如,为列表列表传递ArrayList的令牌).

但是,如果我尝试这样使用它:

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实例.有没有更好的方法来执行此类通用方法?

最佳答案

您可以使用第三方库吗?您基本上是在重塑Guava’s Multimap-ListMultimap< String,String>和SortedSetMultimap< String,Object>是您的两个例子.提供了大量实现-最值得注意的是,对于您的情况,是ArrayListMultimapTreeMultimap.

也就是说,通常只传递一个显式的工厂对象会更容易:

interface Supplier<T> { 
  T get();
}

void putIntoCollection(Map<K, Set<V>>, K, V, Supplier<Set<V>> emptySetSupplier);