为什么 Java 方法没有参数 Collection<?扩展 V> 接受设置 <V>?
Why doesn't a Java method with argument Collection<? extends V> accept Set<V>?
最近,我用了很多Guava Multimap。
偶尔,我需要在 Multimap<K,V>
和 Map<K, Collection<V>
之间进行转换。 Guava API: Multimap#asMap()
已经提供了一个方向。对于另一个方向,我写了一个简单的实用方法如下:
public static <K,V> Multimap<K,V> multimapFromMap(Map<K, Collection<V>> map) {
Multimap<K,V> mmap = HashMultimap.create();
for (Map.Entry<K,Collection<V>> entry : map.entrySet())
mmap.putAll(entry.getKey(), entry.getValue());
return mmap;
}
但是当我尝试写作时
Map<String, Set<String>> aMap = ... ; // obtained from elsewhere
Multimap<String, String> mMap = multimapFromMap(aMap);
我收到此错误消息:
multimapFromMap(java.util.Map<String, java.util.Collection<?>>) cannot be applied to (java.util.Map<java.lang.String, java.util.Set<java.lang.String>>)
但是由于 Set
接口扩展了 Collection
接口,我的代码应该没问题吧?
从 Oracle Java Generics tutorial page,我看到示例“... ArrayList<E>
实现 List<E>
,并且 List<E>
扩展 Collection<E>
。所以 ArrayList<String>
是 List<String>
的子类型,后者是 Collection<String>
的子类型。只要您不改变类型参数,类型之间的子类型关系就会保留 ."
根据评论补充
- 我在
multimapFromMap
方法中用 String
替换了 V
,只是为了让自己放心,我没有混淆一些与泛型相关的概念,但错误仍然存在 ?
替换为错误消息中的 java.lang.Object
。
并不是说您不能在方法需要 Collection<? extends V>
的地方使用 Set<V>
,而是 Map<K, Set<V>>
不是 Map<K, Collection<V>>
的子类型。
如果您将方法更改为接受 Map<K, ? extends Collection<V>>
。
, 会起作用
在许多其他 Whosebug 问题中讨论了此原因,包括 Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?。 (打个比方,Dog
就是Set<V>
,Animal
就是Collection<V>
。)
最近,我用了很多Guava Multimap。
偶尔,我需要在 Multimap<K,V>
和 Map<K, Collection<V>
之间进行转换。 Guava API: Multimap#asMap()
已经提供了一个方向。对于另一个方向,我写了一个简单的实用方法如下:
public static <K,V> Multimap<K,V> multimapFromMap(Map<K, Collection<V>> map) {
Multimap<K,V> mmap = HashMultimap.create();
for (Map.Entry<K,Collection<V>> entry : map.entrySet())
mmap.putAll(entry.getKey(), entry.getValue());
return mmap;
}
但是当我尝试写作时
Map<String, Set<String>> aMap = ... ; // obtained from elsewhere
Multimap<String, String> mMap = multimapFromMap(aMap);
我收到此错误消息:
multimapFromMap(java.util.Map<String, java.util.Collection<?>>) cannot be applied to (java.util.Map<java.lang.String, java.util.Set<java.lang.String>>)
但是由于 Set
接口扩展了 Collection
接口,我的代码应该没问题吧?
从 Oracle Java Generics tutorial page,我看到示例“... ArrayList<E>
实现 List<E>
,并且 List<E>
扩展 Collection<E>
。所以 ArrayList<String>
是 List<String>
的子类型,后者是 Collection<String>
的子类型。只要您不改变类型参数,类型之间的子类型关系就会保留 ."
根据评论补充
- 我在
multimapFromMap
方法中用String
替换了V
,只是为了让自己放心,我没有混淆一些与泛型相关的概念,但错误仍然存在?
替换为错误消息中的java.lang.Object
。
并不是说您不能在方法需要 Collection<? extends V>
的地方使用 Set<V>
,而是 Map<K, Set<V>>
不是 Map<K, Collection<V>>
的子类型。
如果您将方法更改为接受 Map<K, ? extends Collection<V>>
。
在许多其他 Whosebug 问题中讨论了此原因,包括 Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?。 (打个比方,Dog
就是Set<V>
,Animal
就是Collection<V>
。)