Sum*_*ain 8 java generics collections
我想创建一个接受任何Map&a String键的泛型函数,如果映射中没有键,那么它应该创建一个Value Type的新实例(传递)并将其放入map中然后把它返还.
这是我的实施
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;
}
Run Code Online (Sandbox Code Playgroud)
如果我使用普通(非通用)List作为值类型,它可以工作
Map<String,List> myMap;
List value = getValueFromMap(myMap, "aKey", List.class) //works
Run Code Online (Sandbox Code Playgroud)
但不是通用类型列表
Map<String,List<String>> myMap;
List<String> value = getValueFromMap(myMap, "aKey", List.class) //does not work
Run Code Online (Sandbox Code Playgroud)
此外,如果我尝试Map<String, T>通过更改它来使map参数泛型,Map<String, T<?>>它抱怨the type T is not generic; it cannot be parameterized with arguments <?>
通用参数本身可以是通用的吗?
有没有办法创建具有上述要求的功能?
〜更新
感谢大家的所有见解.
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);
Run Code Online (Sandbox Code Playgroud)
您需要最适合您的特定类型String.在您的情况下List.class返回您Class<List<?>>需要特定类型,因此您需要添加强制转换Class<List<String>>
Map<String,List<String>> myMap = new HashMap<String, List<String>>();;
List<String> value = getValueFromMap(myMap, "aKey",
(Class<List<String>>)(Class<?>)ArrayList.class) ;
Run Code Online (Sandbox Code Playgroud)
现在,如果你调用下面的方法
getValueFromMap(myMap, "aKey", List.class)
^^^T is List<String> ^^^ T is List<?> wild char since List.class
will return you Class<List<?>>
Run Code Online (Sandbox Code Playgroud)
因此,您的定义T会导致编译器混淆,因此您将收到编译错误.
你不能创建实例,List.class因为它是接口,你需要它的实现类,所以调用方法ArrayList.class
| 归档时间: |
|
| 查看次数: |
23330 次 |
| 最近记录: |