Take the 2-minute tour ×
static <V> void myMethod(Map<?, V> map)
 Iterator<Entry<?, V>> it = map.entrySet().iterator();

I'm seeing below compilation error:
Type mismatch: cannot convert from Iterator<Map.Entry<capture#5-of ?,V>> to Iterator<Map.Entry<?,V>>

share|improve this question
add comment

1 Answer


Iterator<? extends Entry<?, V>> it = map.entrySet().iterator();

The reason your attempt doesn't work is a bit hard to see, particularly because Iterator<T> does not consume any T (i.e. it doesn't have a method which takes a T as a parameter).

You can't assign an Iterator<Entry<capture#5-of ?,V>> to an Iterator<Entry<?, V>> for the same reason that you can't assign an Iterator<Entry<Integer, String>> to an Iterator<Entry<?, V>>. The capture#5 is just a name used to differentiate the specific ? found in your method's parameter from other distinct wildcard instances. It could just as easily be a concrete type.

The reason this doesn't work is more clear if instead of Iterator you think of a class like List.

List<Entry<Integer, String>> entries = new ArrayList<>();

//this is a compile error, but assume it is possible
List<Entry<?, String>> wildcardEntries = entries; 

//then since this is already possible
wilcardEntries.add(new Entry<String, String>("a", "b"));
Entry<Integer, String> entry1 = entries.get(0);

//this would result in a type error (ClassCastException)
Integer i = entry1.getKey();

By using ? extends Entry<?, V> you're not exposing yourself to this, as you do not claim to know anything about the type of Entry your Iterator can consume, only what it can produce.


Though Jiman deleted his answer, he had a good point that using the for-each loop is a lot cleaner approach (assuming you're just trying to iterate over the entries) that would avoid this issue entirely. This should work:

for ( Entry<?, V> entry : map.entrySet() ) {
share|improve this answer
But i can't use foreach, because the actual method is this: codestatic <V> void fillMapValues(Map<?, V> map, Collection<? extends V> values, V defaultValue) { Iterator<? extends Entry<?, V>> it = map.entrySet().iterator(); for (V value : values) it.next().setValue(value); while (it.hasNext()) it.next().setValue(defaultValue); }code –  Venkata Raju Nov 10 '12 at 7:39
@VenkataRaju: Fair enough, yes Iterator is the right approach then. I assume that this code is meant for maps with a deterministic iteration order, like LinkedHashMap or TreeMap? The order of elements in a HashMap is extremely hard to predict, and can completely change when you insert a new element. –  Mark Peters Nov 10 '12 at 16:35
add comment

Your Answer


