条目集上的通用迭代器

Ven*_*aju 6 java generics

static <V> void myMethod(Map<?, V> map)
{
 Iterator<Entry<?, V>> it = map.entrySet().iterator();
}
Run Code Online (Sandbox Code Playgroud)

我在下面看到编译错误:
类型不匹配:无法转换Iterator<Map.Entry<capture#5-of ?,V>>Iterator<Map.Entry<?,V>>

Mar*_*ers 10

尝试

Iterator<? extends Entry<?, V>> it = map.entrySet().iterator();
Run Code Online (Sandbox Code Playgroud)

你的尝试不起作用的原因有点难以察觉,特别是因为Iterator<T>没有消耗任何东西T(即它没有一个以a T作为参数的方法).

您无法将a分配Iterator<Entry<capture#5-of ?,V>>给a Iterator<Entry<?, V>>,原因与您无法分配Iterator<Entry<Integer, String>>Iterator<Entry<?, V>>.这capture#5只是一个名称,用于区分?方法参数中的特定参数与其他不同的通配符实例.它可以很容易地成为具体类型.

如果不是Iterator你想象一个类,那么这个不起作用的原因就更清楚了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();
Run Code Online (Sandbox Code Playgroud)

通过使用? extends Entry<?, V>你不会暴露自己,因为你没有声称知道任何关于EntryIterator可以消费的类型,只有它可以产生什么.

编辑

虽然Jiman删除了他的答案,但他有一个很好的观点,即使用for-each循环是一种更清洁的方法(假设你只是试图迭代条目),这将完全避免这个问题.这应该工作:

for ( Entry<?, V> entry : map.entrySet() ) {
   //...
}
Run Code Online (Sandbox Code Playgroud)