在以下代码段中:
package test;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
public class WildcardsTest<K, V> {
private Iterator<Map.Entry<K, ? extends Collection<V>>> iterator;
public WildcardsTest(Map<K, ? extends Collection<V>> map) {
iterator = map.entrySet().iterator();
/* Type mismatch: cannot convert from
Iterator<Map.Entry<K,capture#1-of ? extends Collection<V>>> to
Iterator<Map.Entry<K,? extends Collection<V>>> */
}
}
分配不正确,尽管类型似乎完全匹配。
我已经设计了一个肮脏的解决方法,将Collection的类型指定为另一个泛型参数,如下所示:
public class WildcardsTest<K, V, C extends Collection<V>> {
private Iterator<Map.Entry<K, C>> iterator;
public WildcardsTest(Map<K, C> map) {
iterator = map.entrySet().iterator();
}
}
但C
参数实际上是一种“不关心”类型,只会使API复杂化,有没有办法在保持类型安全的同时摆脱它?
感谢。
答案 0 :(得分:4)
这样做会起作用:
private final Iterator<? extends
Map.Entry<K, ? extends Collection<V>>
> iterator;
你仍然可以像这样使用迭代器:
public void foo(){
while(iterator.hasNext()){
Entry<K, ? extends Collection<V>> entry = iterator.next();
Collection<V> value = entry.getValue();
}
}
如需参考,请阅读the get and put principle(最初来自Java Generics and Collections)
答案 1 :(得分:2)
分配不正确,但类型似乎完全匹配。
两个?
- 通配符可以绑定到两个不同的类。换句话说,很明显存在类型不匹配的问题:
private Iterator<Map.Entry<K, ArrayList<V>>> iterator;
public WildcardsTest(Map<K, HashSet<V>> map) {
iterator = map.entrySet().iterator();
}
当你引入C
时,你“强迫它们”引用同一个类。