为什么没有带参数Collection <! - 的Java方法?扩展V - >接受Set <v>?</v>

时间:2015-01-29 22:56:15

标签: java collections set

最近,我一直在使用很多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;

基于评论的补充

  1. 我在V方法中将String替换为multimapFromMap,只是为了向我保证我没有弄清楚一些与泛型相关的概念,但错误仍然存​​在于{ {1}}已在错误消息中替换为?

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?。 (类似地,DogSet<V>AnimalCollection<V>。)