Each of those ? can vary independently, so there's no guarantee that the <?,?>
in the declaration of myMap
matches the <?,?>
in the declaration of set
.
What this means is that once I have a Set<Map<?,?>>
, I can put any type of Map
into that set, because Map<?,?>
is a supertype of all types of Map
. But this is not a property that Set<Map<String,Integer>>
(for example) has - it's far more restrictive in terms of what types of map I can put into it. So Set<Map<?,?>>
is not a supertype of Set<Map<String,Integer>>
. But myMap.entrySet()
could easily be a Set<Map<String,Integer>>
, depending on what myMap
is. So the compiler has to forbid us from assigning it to a variable of type Set<Map<?,?>>
, and that's what's happening.
On the other hand, Set<? extends Map<?,?>>
is a supertype of Set<Map<String,Integer>>
, because Map<String,Integer>
is a subtype of Map<?,?>
. So it's OK to assign myMap.entrySet()
to a variable of type Set<? extends Map<?,?>>
.
Note that there's nothing special about String
and Integer
here, but myMap
has to be a map of something!
You could write
<K, V> void method(Map<K, V> myMap) {
Set<Map.Entry<K, V>> set = myMap.entrySet();
...