0

Recently, I've been using a lot of Guava Multimap.

Occasionally, I need to convert between a Multimap<K,V> and Map<K, Collection<V>. One direction is already provided by the Guava API: Multimap#asMap(). For the other direction, I wrote a simple utility method as follows:

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;
}

But when I tried writing

Map<String, Set<String>> aMap = ... ; // obtained from elsewhere
Multimap<String, String> mMap = multimapFromMap(aMap);

I get this error message:

multimapFromMap(java.util.Map<String, java.util.Collection<?>>) cannot be applied to (java.util.Map<java.lang.String, java.util.Set<java.lang.String>>)

But since the Set interface extends the Collection interface, shouldn't my code be okay?

From Oracle Java Generics tutorial page, I see the example " ... ArrayList<E> implements List<E>, and List<E> extends Collection<E>. So ArrayList<String> is a subtype of List<String>, which is a subtype of Collection<String>. So long as you do not vary the type argument, the subtyping relationship is preserved between the types."

Additions based on comments

  1. I replaced V with String in the multimapFromMap method, just to reassure myself that I wasn't getting some generics-related concepts confused, but the error persists with ? replaced with java.lang.Object in the error message.
Chthonic Project
  • 8,216
  • 1
  • 43
  • 92

1 Answers1

3

It's not that you can't use a Set<V> where a method expects a Collection<? extends V>, it's that Map<K, Set<V>> is not a subtype of Map<K, Collection<V>>.

What would work is if you changed your method to accept Map<K, ? extends Collection<V>>.

The reason for this is discussed in many other StackOverflowQuestions, including Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic? . (In the analogy, Dog is Set<V> and Animal is Collection<V>.)

Community
  • 1
  • 1
Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Ah, I see. I did see that question before asking this one (even SoritriosDelimanolis pointed it out). But I completely messed up the analogy. – Chthonic Project Jan 29 '15 at 23:39