4

我班上有两张地图(我是泛型新手)

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),但 Number 是抽象的。

我该如何解决?

编辑:

我的想法是在没有额外 if 的情况下进行算术运算:

Integer a = getValue(aMap, 15);
a = a + 10;
4

4 回答 4

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
}
于 2013-03-04T10:34:16.360 回答
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泛型的限制:(

于 2013-03-04T10:31:38.267 回答
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);
     }
 };

然后你可以在任何地方使用它,它会按照你指定的方式运行。

于 2013-03-04T11:13:06.650 回答
0

将 0 显式转换为 short ,因为默认情况下它将是 int 。然后转换为 Short wrapper。在 java 中,你不能直接从原始类型转换为不同类型的 Wrapper。

于 2013-03-04T10:39:03.957 回答