2015-01-29 4 views
0

Недавно я использовал много Guava Multimap.Почему не метод Java с аргументом Collection <? extends V> accept Set <V>?

Иногда мне нужно преобразовать Multimap<K,V> и Map<K, Collection<V>. Одно из направлений уже предоставлено API Guava: 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>. До тех пор, пока вы не изменить аргумент типа , отношение подтипирования сохраняется между типами. "

дополнения, основанные на комментарии

  1. я заменил V с String в методе multimapFromMap, только чтобы успокоить себя, что я не получаю некоторые дженерики связанных понятия путают, но ошибка повторяется с ? заменить с сообщением об ошибке java.lang.Object.
+0

Предположительно ваш код не так, как вы присваиваете 'mMap' к' Map'. Отправьте фактический SSCCE. –

+0

@BoristheSpider: исправлено. –

+2

@SotiriosDelimanolis Я не уверен. –

ответ

3

Это не то, что вы не можете использовать Set<V> где метод ожидает 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>.)

+0

А, я вижу. Я задал этот вопрос, прежде чем задавать этот вопрос (даже Соритриос Делиманолис указал на это).Но я полностью испортил аналогию. –

Смежные вопросы