简体   繁体   English

Java:添加到集合的地图

[英]Java: add to map of collections

I'm trying to write a generic function that will add an element to a Map of Collection s. 我正在尝试编写一个通用函数,它将一个元素添加到Collection of Map中。 This works for a Map of List s: 这适用于一个MapList S:

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);
}

I want to make this function work on Map<TKey, Set<TVal>> as well as on Map<TKey, List<TVal>> . 我想让这个函数在Map<TKey, Set<TVal>>以及Map<TKey, List<TVal>> I expect this should be possible because both implement Collection that has the add(TVal) member that I call. 我希望这应该是可能的,因为它们都实现了具有我调用的add(TVal)成员的Collection

My problem is that when I try change the parameter Map<TKey, List<TVal>> map to Map<TKey, ? extends Collection<TVal>> map 我的问题是,当我尝试将参数Map<TKey, List<TVal>> map更改为Map<TKey, ? extends Collection<TVal>> map Map<TKey, ? extends Collection<TVal>> map - I need to somehow replace new ArrayList<>(); Map<TKey, ? extends Collection<TVal>> map - 我需要以某种方式替换new ArrayList<>(); with a call to the constructor of the implementer of Collection . 调用Collection的实现者的构造函数。

You will have to pass an additional parameter to your method - a Supplier of Collection instances. 您必须将另一个参数传递给您的方法 - Collection实例Supplier

Here's one possible implementation : 这是一个可能的实现:

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);
    }
}

Here's another option : 这是另一种选择:

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);
    }
}

And with less code (as suggested by Gerald) : 并且代码更少(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);
}

I tested the second variant : 我测试了第二个变种:

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);
}

Output : 输出:

{String2=[67, 68], String1=[5]}
class java.util.ArrayList : [67, 68]
class java.util.HashSet : [5]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM