java吧 关注:1,238,565贴子:12,708,731
  • 31回复贴,共1

【泛型】偷懒不好偷啊

只看楼主收藏回复

想写个方法,用来偷懒,结果写了一半写不下去了,一定是泛型的打开方式不对。。。
已知:经常需要用Map<String,Integer>,Map<String,Long>,......这种key固定为String,value为Number子类(基本数值类型的包装类) 的map做 加 操作。
于是,想写个通用的addKey方法,传入map,key,value ,对于map中没有的key,直接put进去<k,v> ,对于key已经存在的,取value进行加操作。
然后,就写出了这个:

else里 不知道咋写了。。。
貌似问题是: 代码阶段,value进行加操作之后类型必须还是 'T' ,但是我不知道该怎么搞了。
我想了两种其他方法,大概可行,不过感觉比较麻烦,效率也不高
一:定义个接口 Addable<T> 包含一个 add(T t)。
然后针对每个数值包装类写个My*** implements Addable<My***> 。
然后方法改成 <T extends Addable> Map<String, T> addKey(Map<String, T> map, String key, T t)。
感觉上可以实现,不过Map只能定义为Map<String,My***>这种了,用起来有点不太方便,取value值的时候需要用get方法,不能在My***的阶段自动“装箱,拆箱”。
二:直接 Map<String,Object> addKey(Map<String,Object> map,String key,Object v)();
这样就不存在没法put的情况了,但是在加操作和 取value的时候需要判断class类型,很蛋疼的赶脚。。。
求支招,求解惑


IP属地:辽宁1楼2013-11-16 14:58回复
    对 偷懒不好偷


    IP属地:浙江2楼2013-11-16 15:11
    收起回复
      我来看看


      IP属地:重庆3楼2013-11-16 15:30
      收起回复
        int sum 改成 Integer sum
        map.add(key,(T)sum);
        试试 int 不是Number的子类 Integer不是T类型 所以出错


        IP属地:福建4楼2013-11-16 16:01
        收起回复
          t.getClass().cast(sum)


          IP属地:广西5楼2013-11-16 16:17
          收起回复
            只是要put的话可以把map强制转型为无泛型的Map,但是总觉得你这样类型安全还是有点问题……


            IP属地:广西6楼2013-11-16 16:47
            收起回复
              public static <T extends Number> Map<String, T> addKey(Map<String, T> map,
              String key, T t) {
              if (map == null) {
              map = new HashMap<String, T>();
              }
              T value = map.get(key);
              if (value == null) {
              map.put(key, t);
              } else {
              Class cs = t.getClass();
              Number num = null;
              if (cs == Integer.class) {
              num = (Integer) t + value.intValue();
              } else if (cs == Long.class) {
              num = (Long) t + value.longValue();
              } else if (cs == Byte.class) {
              num = (Byte) t + value.byteValue();
              } else if (cs == Double.class) {
              num = (Double) t + value.doubleValue();
              } else if (cs == Float.class) {
              num = (Float) t + value.floatValue();
              } else if (cs == Short.class) {
              num = (Short) t + value.shortValue();
              } else if (cs == BigDecimal.class) {
              num = ((BigDecimal) t).add((BigDecimal) value);
              } else if (cs == BigInteger.class) {
              num = ((BigInteger) t).add((BigInteger) value);
              } else if (cs == AtomicInteger.class) {
              num = ((AtomicInteger) t).getAndAdd(value.intValue());
              } else if (cs == AtomicLong.class) {
              num = ((AtomicLong) t).getAndAdd(value.longValue());
              }
              map.put(key, (T) num);
              }
              return map;
              }
              public static void main(String[] args)
              Map<String, Long> map = null;
              map = addKey(map, "aaa", 100L);
              addKey(map, "bbb", 1L);
              addKey(map, "aaa", 1L);
              for (Map.Entry<String, Long> e : map.entrySet()) {
              System.out.println(e.getKey() + " -- " + e.getValue());
              }
              }
              @夜轩浪@纯金键盘@ziyouwuji@zzb12 ,多谢你们的帮忙。
              我这样写 貌似可以实现了, 泛型好神奇~ 哈哈


              IP属地:辽宁8楼2013-11-16 17:15
              收起回复
                想把泛型用清白,得先把反射搞明白。
                用反射,是有可能在【运行时】判断泛型参数类型的。
                http://sunting-bcwl.iteye.com/blog/768989


                IP属地:湖北10楼2013-11-16 20:38
                收起回复