Alf*_*Alf 5 java generics wildcard
我有一个带有以下签名的方法:
public <T> int numberOfValues(Map<T, Set<?>> map)
Run Code Online (Sandbox Code Playgroud)
但是我不能称之为传递Map<String, Set<String>>.例如,以下内容无法编译:
Map<String, Set<String>> map = new HashMap<>();
numberOfValues(map);
Run Code Online (Sandbox Code Playgroud)
错误消息是:
numberOfValues (java.util.Map<java.lang.String,java.util.Set<?>>) in class cannot be applied to (java.util.Map<java.lang.String,java.util.Set<java.lang.String>>)
Run Code Online (Sandbox Code Playgroud)
但是,如果我改为以下一切都很好:
public <T, V> int numberOfValues(Map<T, Set<V>> map)
Run Code Online (Sandbox Code Playgroud)
但是我对此并不感兴趣V,因为我只想知道每组的大小.
为了完整起见,这是整个方法:
public <T, V> int numberOfValues(Map<T, Set<V>> map) {
int n = 0;
for (T key : map.keySet()) {
n += map.get(key).size();
}
return n;
}
Run Code Online (Sandbox Code Playgroud)
我知道它也可以像这样完成,但不是问题的重点:)
public <T> int numberOfValues(Map<?, Set<T>> map) {
int n = 0;
for (Set<T> value : map.values()) {
n += value.size();
}
return n;
}
Run Code Online (Sandbox Code Playgroud)
更新:实现同样的另一种方式
public <T> int numberOfValues(Map<?, Set<T>> map) {
int n = 0;
for (Object key : map.keySet()) {
n += map.get(key).size();
}
return n;
}
Run Code Online (Sandbox Code Playgroud)
最后更新: 感谢Jorn的回答,这是最终的实施......
public int numberOfValues(Map<?, ? extends Set<?>> map) {
int n = 0;
for (Set<?> value : map.values()) {
n += value.size();
}
return n;
}
Run Code Online (Sandbox Code Playgroud)
您错过了Set<?>也被用作通用参数的事实.仿制药是不变的.即,当参数为时Map<String, Set<?>>,传递的参数必须是精确的Map<String, Set<?>(或子类型).而Set<V>推断出类型参数.
您可以使用有界通配符来解决此问题:
public <T> int numberOfValues(Map<T, ? extends Set<?>> map) {
...
}
Run Code Online (Sandbox Code Playgroud)