我班上有两张地图(我是仿制药的新手)
private Map<Integer, Integer> aMap = new ConcurrentHashMap<Integer, Integer>();
private Map<Integer, Short> bMap = new HashMap<Integer, Short>();
如果地图中不存在密钥,我想获得零值。所以我制作了这个包装方法来最小化输入containsKey(key)
@SuppressWarnings("unchecked")
private <T extends Number> T getValue (Map<Integer, T> map, Integer key) {
return (T) ((map.containsKey(key)) ? map.get(key) : 0);
}
我称之为
Integer a = getValue(aMap, 15); //okay in any case
Short b = getValue(bMap, 15); //15 key does not exist
对于第二种情况,它给了我:
ClassCastException: java.lang.Integer cannot be cast to java.lang.Short
所以我可能需要做: new Number(0)
之类的事情,但是数字是抽象的。
我该如何解决?
修改
我的想法是在没有额外ifs的情况下进行算术运算:
Integer a = getValue(aMap, 15);
a = a + 10;
答案 0 :(得分:6)
一种方法是将默认值作为函数的参数提供:
private <T extends Number> T getValue (Map<Integer, T> map, Integer key, T dflt) {
return (T) ((map.containsKey(key)) ? map.get(key) : dflt);
}
public static void main(String[] args) {
Integer a = getValue(aMap, 15, 0); //okay in any case
Short b = getValue(bMap, 15, (short)0); //15 key does not exist
}
答案 1 :(得分:3)
好吧,如果不以代码可以查看的方式提供T
,你就无法做很多事情。
此时最简单的方法可能是保留0值的映射:
private static Map<Class<?>, Number> ZERO_VALUES = createZeroValues();
private static Map<Class<?>, Number> createZeroValues() {
Map<Class<?>, Number> ret = new HashMap<Class<?>, Number>();
ret.put(Integer.class, (int) 0);
ret.put(Short.class, (short) 0);
ret.put(Long.class, (long) 0);
// etc
}
然后:
private <T extends Number> T getValue (Map<Integer, T> map, Integer key, Class<T> clazz) {
return clazz.cast(map.containsKey(key) ? map.get(key) : ZERO_VALUES.get(clazz));
}
然后你不得不把它称为:
Short b = getValue(bMap, 15, Short.class);
基本上这是Java泛型的限制:(
答案 2 :(得分:2)
在这种情况下,我只是覆盖get()
方法:
private Map<Integer, Short> bMap = new HashMap<Integer, Short>() {
@Override
public Short get(Object key) {
return containsKey(key) ? super.get(key) : new Short(0);
}
};
然后你可以在任何地方使用它,它的行为与你指定的一样。
答案 3 :(得分:0)
将0显式缩短为默认值,因为它默认为int。然后转换为Short包装器。在java中,你不能直接从原语转换为不同类型的Wrapper。