Generic 0 cannot be added to java.lang.Short

I have two cards in my class (I'm new to generics)

private Map<Integer, Integer> aMap = new ConcurrentHashMap<Integer, Integer>(); private Map<Integer, Short> bMap = new HashMap<Integer, Short>(); 

If there is no key on the card, I want to get a null value. So I made this wrapper method to minimize the typing of 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); } 

I call it like

 Integer a = getValue(aMap, 15); //okay in any case Short b = getValue(bMap, 15); //15 key does not exist 

In the second case, it gives me:

 ClassCastException: java.lang.Integer cannot be cast to java.lang.Short 

Therefore, probably, I will need to do something like : new Number(0) , but Number is abstract.

How to fix it?

EDIT:

My idea is to do arithmetic operations without additional ifs:

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

One way is to specify a default value as an argument to your function:

 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 } 
+6
source

Well, you cannot do this without providing T in such a way that the code can look.

The simplest approach at this point is probably to save a map of 0 values:

 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 } 

Then:

 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)); } 

Then you, unfortunately, should call it like:

 Short b = getValue(bMap, 15, Short.class); 

This is basically a limitation of Java generics :(

+3
source

In such situations, I simply override the get() method:

  private Map<Integer, Short> bMap = new HashMap<Integer, Short>() { @Override public Short get(Object key) { return containsKey(key) ? super.get(key) : new Short(0); } }; 

Then you can just use it anywhere, and it will behave as you indicated.

+2
source

Refuse from 0 to short-term as by default it will be int. And then convert to a short wrapper. In java, you cannot directly convert from a primitive to another type of Wrapper.

0
source

All Articles