I want to create a generic function that takes any Map & a String key, if the key is not present in the map, then it should create a new instance of the Value Type (which is passed) & put it in the map & then return it.
Here is my implementation
public <T> T getValueFromMap(Map<String, T> map, String key, Class<T> valueClass){
T value = map.get(key);
if (value == null){
try {
value = valueClass.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
map.put(key, value);
}
return value;
}
It works if I use it with a normal (not generic) List as the value type,
Map<String,List> myMap;
List value = getValueFromMap(myMap, "aKey", List.class) //works
but not with generic type lists
Map<String,List<String>> myMap;
List<String> value = getValueFromMap(myMap, "aKey", List.class) //does not work
Also if I try to make Map<String, T> map parameter generic by changing it to Map<String, T<?>> it complains that the type T is not generic; it cannot be parameterized with arguments <?>
Can the generic parameters be themselves made generic?
Is there any way to create function with above mentioned requirements?
~Update
Thanks for all the insightful answers everyone.
I have verified that the accepted solution works for any value type with this code
Map<String, Map<String, List<String>>> outer =
new HashMap<String, Map<String,List<String>>>();
Map<String, List<String>> inner = getValueFromMap(outer, "b",
(Class<Map<String, List<String>>>)(Class<?>)HashMap.class);
List<String> list = getValueFromMap(inner, "a",
(Class<List<String>>)(Class<?>)ArrayList.class);
You need most specific types which is
Stringin your case.List.classreturns youClass<List<?>>in your case you need specific type so you will need to add castClass<List<String>>Now if you invoke method like below
So your defination of
Tis causing confusion to Compiler so you are getting compile error.You can not create instance of
List.classsince it is interface you will need implemention class of it so call method withArrayList.class