Java:添加到集合的地图

yto*_*ano 2 java generics collections dictionary

我试图写一个通用的函数,将一个元素添加到MapCollection秒.这适用于一个MapListS:

public static <TKey, TVal> void addToMapOfLists(Map<TKey, List<TVal>> map, TKey key, TVal val) {
    List<TVal> list = map.get(key);
    if (list == null) {
        list = new ArrayList<>();
        list.add(val);
        map.put(key, list);
    } else
        list.add(val);
}
Run Code Online (Sandbox Code Playgroud)

我想就这个函数的工作Map<TKey, Set<TVal>>以及对Map<TKey, List<TVal>>.我希望这应该是可能的,因为两个实现Collection都有add(TVal)我调用的成员.

我的问题是,当我尝试将参数更改Map<TKey, List<TVal>> mapMap<TKey, ? extends Collection<TVal>> map- 我需要以某种方式替换new ArrayList<>();为对实现者的构造函数的调用Collection.

Era*_*ran 7

您将有一个额外的参数传递给你的方法-一个SupplierCollection实例.

这是一个可能的实现:

public static <TKey, TVal, TCol extends Collection<TVal>> void addToMapOfCollections(Map<TKey, Collection<TVal>> map, TKey key, TVal val, Supplier<TCol> supplier) 
{
    Collection<TVal> col = map.get(key);
    if (col == null) {
        col = supplier.get ();
        col.add(val);
        map.put(key, col);
    } else {
        col.add(val);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是另一种选择:

public static <TKey, TVal> void addToMapOfCollections(Map<TKey, Collection<TVal>> map, TKey key, TVal val, Supplier<Collection<TVal>> supplier)
{
    Collection<TVal> col = map.get(key);
    if (col == null) {
        col = supplier.get ();
        col.add(val);
        map.put(key, col);
    } else {
        col.add(val);
    }
}
Run Code Online (Sandbox Code Playgroud)

并且代码更少(Gerald建议):

public static <TKey, TVal> void addToMapOfCollections(Map<TKey, Collection<TVal>> map, TKey key, TVal val, Supplier<Collection<TVal>> supplier)
{
    map.putIfAbsent(key, supplier.get());
    map.get(key).add(val);
}
Run Code Online (Sandbox Code Playgroud)

我测试了第二个变种:

Map<String,Collection<Integer>> map = new HashMap<String, Collection<Integer>>();
addToMapOfCollections(map,"String1",5,HashSet::new);
addToMapOfCollections(map,"String2",67,ArrayList::new);
addToMapOfCollections(map,"String2",68,ArrayList::new);
System.out.println (map);
for (Collection<Integer> col : map.values ()) {
    System.out.println (col.getClass () + " : " + col);
}
Run Code Online (Sandbox Code Playgroud)

输出:

{String2=[67, 68], String1=[5]}
class java.util.ArrayList : [67, 68]
class java.util.HashSet : [5]
Run Code Online (Sandbox Code Playgroud)