Reputation: 400
When I try to create object as below :
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
What is wrong syntactically, can any one explain me?
Upvotes: 11
Views: 515
Reputation: 10553
It is similar error like
List<Animal> list = new ArrayList<Dog>();
Parameterized type should be of same type at both end. There is no inheritance (IS-A) concept. If you still want to use it then use wildcard(?) with extend/super keyword which is allowed only at left side of the equals sign.
List<Animal> list = new ArrayList<Dog>(); // is not allowed
but
Animal[] animal = new Dog[10]; //is allowed
animal[0] = new Dog(); // is allowed
where it will later fail and throw exception if somebody tries to add Cat
(extends Animal) object.
animal[1] = new Cat(); //compiles fine but throws java.lang.ArrayStoreException at Runtime.
Remember animal[1]
or animal[index]
is holding reference
of Dog. So Dog
reference variable can refer to Dog
object not Cat
object.
So to avoid such scenario, JSL have made such changes in generics list/Collection. This answer is also applicable for your question(Map
).
Parameterized type should be of same type at both end.
List<Animal> list = new ArrayList<Animal>();
Upvotes: 10
Reputation: 136162
Try this
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
It is easer to explain on a simpler example
Set<Number> set = new HashSet<Integer>();
is not allowed, because then you could add a Double to HashSet of Integers
set.add(1.0)
Note that
Set<? extends Number> set = new HashSet<Integer>();
does not allow to add anything but null
to the set. But you can only read Numbers from it
You can find more info here http://docs.oracle.com/javase/tutorial/extra/generics/wildcards.html
Upvotes: 6
Reputation: 159874
Generics are not co-variant. You can use:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
^ ^
--------------^------------------- becomes ------^ |
-----------------must remain as type ---------------
While the Map
on the outer left hand side of the assignment can "become" a HashMap
as assigned, the same cannot be applied to any types that appear as generic parameters.
Edit:
As noted by @Keppil, you can use the bounded wildcard syntax:
Map<Integer, ? extends Map<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Note that this syntax will not allow entries to be added to the map but is useful as a type to be passed to and from methods.
Some references:
Upvotes: 20
Reputation: 1026
Map<String, Integer>
is not same as HashMap<String, Integer>
. Thats the problem.
Actually HashMap implements Map interface. So it should be ? extends Map<String, Integer>
on left hand side
Upvotes: 3
Reputation: 8090
you need something like this:
Map<Integer, Map<String, Integer>> myMap = new HashMap<Integer, Map<String, Integer>>();
myMap.put(1, new HashMap<String, Integer>());
Upvotes: 3
Reputation: 12843
Try this:
Map<Integer, HashMap<String, Integer>> myMap = new HashMap<Integer, HashMap<String, Integer>>();
Upvotes: 2