2016-06-30 17 views
2

Mapに要素を追加する汎用関数を書き込もうとしています。Collectionです。これはMapListのsのために働く:Java:コレクションのマップに追加

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

は私がMap<TKey, Set<TVal>>上だけでなく、Map<TKey, List<TVal>>に、この機能の作品を作りたいです。両方とも私が呼ぶadd(TVal)のメンバーを持っているCollectionを実装しているので、これが可能になるはずです。

私の問題は、私がしようとすると、Map<TKey, ? extends Collection<TVal>> mapにパラメータMap<TKey, List<TVal>> mapを変更することである - 私は何とかCollectionの実装のコンストラクタを呼び出してnew ArrayList<>();を交換する必要があります。

+0

? Javaでのリフレクションによって、実行時にパラメータMapのジェネリック型が見つからないことがあります。 –

+0

可能な複製http://stackoverflow.com/questions/254351/map-of-collections –

+0

明らかに(C++由来) - リストまたはセットはマップのタイプに応じて選択されます。いずれかのデフォルトctorが呼び出されます。 – ytoledano

答えて

7

メソッドに追加のパラメータ(Supplier,Collectionインスタンス)を渡す必要があります。

ここに1つの可能な実装があります:

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

少ないコード(ジェラルドにより示唆されるように)と::

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

私は第二の変形例をテストし

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

ここでは別のオプションがあります:

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

出力:あなたがリストまたはセットを使用することを選択した方法

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

'putIfAbsent'を使用してコレクションを初期化することで、このメソッドにさらに1つの簡素化を加えることができます。' map.putIfAbsent(key、supplier.get()); map.get(key).add(value) ' –

+0

@GeraldMücke良い提案。 – Eran

関連する問題