Reputation: 4827
I want to store an Integer
or a Double
, both extending from Number
, into a HashMap
, and retrieve them without casting. The reason is that I'll eventually have many have many different subtypes (I am only using Number
/Integer
for illustration), and I don't want to have to write a new method when a different subtype is introduced. Can I structure and call getFromMap()
below without having to do the cast to Double
or Integer
?
public class MapOfContent {
static Map<String, Number> hm = new HashMap<String, Number>();
public static void main(String[] args) {
addToMap(hm, Integer.valueOf(3), "An Integer");
addToMap(hm, Double.valueOf(3.4), "A Double");
Double d;
d = (Double) getFromMap(hm, "A Double");
//d = getFromMap(hm, "A Double");
System.out.println("Result-> " + d);
}
private static void addToMap(Map<String, ? super Number> hashmap, Number c, String key) {
hashmap.put(key, c);
}
private static <T> Number getFromMap(Map<String, ? extends Number> hashmap, String cmsKey) {
return hashmap.get(cmsKey);
}
}
Upvotes: 3
Views: 215
Reputation: 49724
If you're storing objects of different classes in a collection and when you fetch them, you need to access fields/methods of their actual type and not just their common ancestor, then no.
There will be an explicit cast somewhere, the best you can do is to push it deep and hide it from all the other parts of the code, as ClassToInstanceMap
does.
Upvotes: 0
Reputation: 198023
There's no way to actually make this approach genuinely typesafe; what if you tried (Double) getFromMap(hm, "An Integer")
? That should fail.
One potential alternative might be to use the actual Class
object as a key, for example using a Guava ClassToInstanceMap
:
ClassToInstanceMap<Number> map = MutableClassToInstanceMap.create();
map.putInstance(Integer.class, Integer.valueOf(3));
map.putInstance(Double.class, Double.valueOf(3.4));
Double aDouble = map.getInstance(Double.class); // no cast required
Upvotes: 2