[英]Set not applicable for Collection in generic method with Java
I defined a generic function in java with the signature 我用签名在Java中定义了一个泛型函数
<V> List<V> sortedValuesFromMap(Map<?, Collection<V>> keysValues, Comparator<V> comp)
which takes a Map mapping any type of keys to a Collection of some defined type V, and a comparator of type V. The method works great and the Java compiler does not complain about type incompatibility. 它使用Map将任何类型的键映射到一些已定义的V类型的Collection以及V类型的比较器。该方法很好用,并且Java编译器不会抱怨类型不兼容。
But now when I want to apply this method to a map of the type Map<String, Set<String>>
and the AlphanumComparator
(see here ) the compiler says : 但是现在,当我想将此方法应用于
Map<String, Set<String>>
和AlphanumComparator
类型的Map<String, Set<String>>
(请参见此处 )时,编译器会说:
The method
sortedValuesFromMap(Map<?,Collection<V>>, Comparator<V>)
in the type MyUtils is not applicable for the arguments (Map<String,Set<String>, AlphanumComparator
)sortedValuesFromMap(Map<?,Collection<V>>, Comparator<V>)
不适用于参数(Map<String,Set<String>, AlphanumComparator
)
Turning Collection
to Set
in the signature of sortedValuesFromMap
would fix it – but I do not want to do that. 将
sortedValuesFromMap
的签名中的Collection
Set
为Set
可以解决该问题-但我不想这样做。 So why is Java forcing me to do so, although Set<E>
is implementing Collection<E>
? 那么,尽管
Set<E>
实现了 Collection<E>
,但是为什么Java强制我这样做呢?
PS: If someone is interested in my code: 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;
}
Just as a List<Dog>
is not a List<Animal>
, a Map<String, Set<String>>
is not a Map<String, Collection<String>>
and it's not a Map<?, Collection<String>>
. 就像
List<Dog>
不是List<Animal>
, Map<String, Set<String>>
不是Map<String, Collection<String>>
并且它不是Map<?, Collection<String>>
。
The solution here is to add a wildcard in place of Set
to allow a subclass in the generic type parameter. 这里的解决方案是添加一个通配符代替
Set
以允许泛型类型参数中的子类。
// Add v
public static <V> List<V> sortedValuesFromMap(Map<?, ? extends Collection<V>> keysValues,
Comparator<V> comp) {
Your problem is that Map<String,Set<V>>
is not a subtype of Map<String,Collection<V>>
. 您的问题是
Map<String,Set<V>>
不是Map<String,Collection<V>>
的子类型。 Think about what type x
can be, if it's legal to write x.put("Hello",new ArrayList<V>());
考虑一下
x
可以是什么类型,如果写x.put("Hello",new ArrayList<V>());
是合法的x.put("Hello",new ArrayList<V>());
In this case, x
could be a Map<String,Collection<V>>
, since an ArrayList<V>
is certainly a Collection<V>
. 在这种情况下,
x
可以是Map<String,Collection<V>>
,因为ArrayList<V>
当然是Collection<V>
。 But it couldn't be a Map<String,Set<V>>
, since an ArrayList<V>
is not a Set<V>
. 但这不能是
Map<String,Set<V>>
,因为ArrayList<V>
不是Set<V>
。 Therefore it's untrue to say that any Map<String,Set<V>>
"is a" Map<String,Collection<V>>
. 因此,不能说任何
Map<String,Set<V>>
是一个Map<String,Collection<V>>
。
The type that you want is either Map<String,? extends Collection<V>>
您想要的类型是
Map<String,? extends Collection<V>>
Map<String,? extends Collection<V>>
or Map<?,? extends Collection<V>>
Map<String,? extends Collection<V>>
或Map<?,? extends Collection<V>>
Map<?,? extends Collection<V>>
. Map<?,? extends Collection<V>>
。 Both Map<String,Set<V>>
and Map<String,Collection<V>>
are subtypes of these types. Map<String,Set<V>>
和Map<String,Collection<V>>
都是这些类型的子类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.