最近,我一直在使用很多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开始,我看到了示例&#34; ...... ArrayList<E>
实施List<E>
,List<E>
延伸Collection<E>
。因此ArrayList<String>
是List<String>
的子类型,它是Collection<String>
的子类型。 只要您不改变类型参数,就会在类型之间保留子类型关系。&#34;
基于评论的补充
V
方法中将String
替换为multimapFromMap
,只是为了向我保证我没有弄清楚一些与泛型相关的概念,但错误仍然存在于{ {1}}已在错误消息中替换为?
。 答案 0 :(得分:3)
并非您不能使用方法需要Set<V>
的{{1}},Collection<? extends V>
不是Map<K, Set<V>>
的子类型Map<K, Collection<V>>
。
如果您将方法更改为接受Map<K, ? extends Collection<V>>
,那么将的工作原理。
在许多其他StackOverflowQuestions中讨论了其原因,包括Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?。 (类似地,Dog
是Set<V>
而Animal
是Collection<V>
。)