我在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;
}
答案 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>>
都是这些类型的子类型。