设置不适用于使用Java的泛型方法中的Collection

时间:2014-03-06 20:34:02

标签: java generics set generic-collections

我在java中使用签名

定义了一个泛型函数

<V> List<V> sortedValuesFromMap(Map<?, Collection<V>> keysValues, Comparator<V> comp)

将任何类型的键映射到某个已定义类型V的集合,以及类型为V的比较器。该方法效果很好,Java编译器不会抱怨类型不兼容。

但现在,当我想将此方法应用于Map<String, Set<String>>类型和AlphanumComparator(请参阅here)的地图时,编译器会说:

  

方法sortedValuesFromMap(Map<?,Collection<V>>, Comparator<V>)   在类型MyUtils中不适用于参数   (Map<String,Set<String>, AlphanumComparator

Collection的签名中将Set转为sortedValuesFromMap会解决问题 - 但我不想这样做。那么为什么Java强迫我这样做,虽然Set<E>implementing Collection<E>

PS:如果有人对我的代码感兴趣:

public static <V> List<V> sortedValuesFromMap(Map<?, Collection<V>> keysValues,
        Comparator<V> comp) {
    List<V> values = new LinkedList<V>();
    for (Collection<V> col : keysValues.values()) {
        values.addAll(col);
    }
    Collections.sort(values, comp);
    return values;
}

2 个答案:

答案 0 :(得分:2)

List<Dog> is not a List<Animal>一样,Map<String, Set<String>>不是Map<String, Collection<String>>而且不是Map<?, Collection<String>>

这里的解决方案是添加一个通配符代替Set以允许泛型类型参数中的子类。

//                                                   Add v
public static <V> List<V> sortedValuesFromMap(Map<?, ? extends Collection<V>> keysValues,
    Comparator<V> comp) {

答案 1 :(得分:0)

您的问题是Map<String,Set<V>>不是Map<String,Collection<V>>的子类型。如果写x

是合法的,请考虑x.put("Hello",new ArrayList<V>());可以是什么类型

在这种情况下,x可以是Map<String,Collection<V>>,因为ArrayList<V>肯定是Collection<V>。但它不能是Map<String,Set<V>>,因为ArrayList<V>不是Set<V>。因此,任何Map<String,Set<V>>“都是”Map<String,Collection<V>>是不正确的。

您需要的类型是Map<String,? extends Collection<V>>Map<?,? extends Collection<V>>Map<String,Set<V>>Map<String,Collection<V>>都是这些类型的子类型。

相关问题