Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map<String, Map<String, Boolean>> myMap = new HashMap<String,HashMap<String,Boolean>>();

Why doesn't that work in java, but this does

Map<String, Map<String, Boolean>> myMap = new HashMap<String,Map<String,Boolean>>();

Just to clarify the below alteration of the nested HashMap shows a compiler error, whereas the above does not not; with a Map (not hashmap)

Map<String, Map<String, Boolean>> myMap = new HashMap<String,HashMap<String,Boolean>>();
like image 353
NimChimpsky Avatar asked Dec 10 '22 14:12

NimChimpsky


2 Answers

This is because generics in Java are invariant, i.e. even if class B is an A, a Collection<B> is not a Collection<A>.

And this is for a good reason. If your example were legal, this would be possible:

Map<String, HashMap<String, Boolean>> myHashMap = new HashMap<String,HashMap<String,Boolean>>();
Map<String, Map<String, Boolean>> myMap = myHashMap;
myMap.put("oops", new TreeMap<String, Boolean>());
HashMap<String, Boolean> aHashMap = myMap.get("oops"); // oops - ClassCastException!
like image 66
Péter Török Avatar answered Dec 12 '22 04:12

Péter Török


In the second case myMap is a map which keys are of type String and values are of type Map<String, Boolean>. HashMap<String, Boolean> is not a Map<String, Boolean> it implements it. Therefore, this will compile:

Map<String, ? extends Map<String, Boolean>> myOtherMap = 
    new HashMap<String,HashMap<String,Boolean>>();
like image 33
Boris Pavlović Avatar answered Dec 12 '22 04:12

Boris Pavlović