我有两个由{i} Multimap
和(ii)String
索引的Integer
个Double
以及一个输出{{{ 1}}秒。
String
我想将public static void outputInteger(Multimap<Integer, String> map) {
for (Integer key : map.keySet()) {
Collection<String> strings = map.get(key);
output(strings);
}
}
public static void outputDouble(Multimap<Double, String> map) {
for (Double key : map.keySet()) {
Collection<String> strings = map.get(key);
output(strings);
}
}
作为Number
和Integer
Double
但带星号的行无法编译
public static void outputNumber(Multimap<? extends Number, String> map) {
for (Number key : map.keySet()) {
Collection<String> ids = map.get(key); //**
}
}
我该如何解决这个问题?
答案 0 :(得分:9)
声明
Multimap<? extends Number, String> map;
表示地图的密钥类型是未知但具有数字的特定子类型(包括)。换句话说,编译器认为它可能是Multimap<Integer, String>
,Multimap<Short, String>
或Multimap<Number, String>
等。因此,您无法调用map.get(Number)
,因为到目前为止正如编译器所知,它可能是Multimap<Double, String>
。
使用put
更明显无法做到这一点。你应该put(Number, String)
map
吗?不,因为如果它恰好是Multimap<Integer, String>
,那么您可以添加一个Double
密钥,这将违反地图的完整性。
使用正常的Map<K, V>
界面,这不是问题,因为get
定义为get(Object)
,而不是get(K)
。
保罗的回答对这种情况有很好的解决方法。本质上,他使用中间泛型方法为未知类型(在本例中由capture#5-of ? extends Number
表示)提供名称(类型参数T
)。这允许您关联在两个不同上下文中发生的捕获,以便您可以跨这些上下文执行某些操作。
答案 1 :(得分:7)
您应该可以使用generic method来实现您的目标:
public static <T extends Number> void outputNumber(Multimap<T, String> map) {
for (T key : map.keySet()) {
Collection<String> strings = map.get(key);
output(strings);
}
}
它不适用于通配符的原因是因为? extends Number
表示某些未知类型是Number
。同时,Number key
可以引用其他一些不兼容的类型(对于所有编译器都知道)。
答案 2 :(得分:7)
public static void output(Multimap<? extends Number, String> map) {
for (Collection<String> strings : map.asMap().values()) {
output(strings);
}
}
答案 3 :(得分:0)
问题是你没有传递泛型参数但声明它。
如果您有这种类型的实现,则不会发生错误
public static <T extends Number> void outputNumber(Multimap<T, String> map) {
for (T key : map.keySet()) {
map.get(key);
}
}