4

我有两个由 (i) s 和 (ii) MultimapsString索引的s 和一个输出 s 列表的例程。IntegerDoubleString

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用作和的超IntegerDouble

public static void outputNumber(Multimap<? extends Number, String> map) {
    for (Number key : map.keySet()) {
        Collection<String> ids = map.get(key); //** 
    }
}

但带星号的行无法编译

The method get(capture#5-of ? extends Number) in the type 
Multimap<capture#5-of ? extends Number,String> is not 
applicable for the arguments (Number)

我该如何解决这个问题?

4

4 回答 4

9

宣言

Multimap<? extends Number, String> map;

表示 map 的键类型是Number 的未知但特定的子类型(包括)。换句话说,编译器认为它可能是 a Multimap<Integer, String>, or Multimap<Short, String>, orMultimap<Number, String>等​​。因此,您不能调用map.get(Number),因为据编译器所知,它可能是 a Multimap<Double, String>

无法做到这一点的原因在put. 你应该可以做put(Number, String)map?不,因为如果它碰巧是 a Multimap<Integer, String>,那么您可以添加一个Double密钥,这将违反地图的完整性。

使用普通Map<K, V>界面,这不是问题,因为get定义为get(Object),而不是get(K)

保罗的回答对这种情况有很好的解决方法。本质上,他使用中间泛型方法为未知类型(在本例中由 表示capture#5-of ? extends Number)命名(类型参数T)。这允许您将发生在两个不同上下文中的捕获关联起来,以便您可以在这些上下文中执行某些操作。

于 2013-04-16T16:26:19.297 回答
7

您应该能够使用通用方法来实现您想要的:

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意味着某些未知类型is 或 extends Number。同时,Number key可以引用其他一些不兼容的类型(编译器都知道)。

于 2013-04-16T16:24:16.083 回答
7
public static void output(Multimap<? extends Number, String> map) {
    for (Collection<String> strings : map.asMap().values()) {
        output(strings);
    }
}
于 2013-04-16T16:28:19.600 回答
0

问题是您没有传递泛型参数而是声明它。

如果您有这种类型的实现,则不会发生错误

public static <T extends Number> void outputNumber(Multimap<T, String> map) {

        for (T key : map.keySet()) {
            map.get(key);
        }
    }
于 2013-04-16T16:28:12.743 回答