How can I convert MultiMap<Integer, Foo> to Map<Integer, Set<Foo>> using Guava?

guava, java, set

Solution

Look at this issue and comment #2 by Kevin Bourrillion, head Guava dev:

You can double-cast the `Map<K, Collection<V>>` first to a raw Map and then to the `Map<K, Set<V>>` that you want. You'll have to suppress an unchecked warning and you should comment at that point, "Safe because SetMultimap guarantees this." I may even update the SetMultimap javadoc to mention this trick.

So do unchecked cast:

@SuppressWarnings("unchecked") // Safe because SetMultimap guarantees this.
final Map<Integer, Set<OccupancyType>> mapOfSets = 
    (Map<Integer, Set<OccupancyType>>) (Map<?, ?>) pkgPOP.asMap();

EDIT:

Since Guava 15.0 you can use helper method to do this in more elegant way:

Map<Integer, Set<OccupancyType>> mapOfSets = Multimaps.asMap(pkgPOP);

Problem

I'm using MultiMap from Google Guava 12 like this: ``` Multimap<Integer, OccupancyType> pkgPOP = HashMultimap.create(); ``` after inserting values into this multimap, I need to return: ``` Map<Integer, Set<OccupancyType>> ``` However, when I do: ``` return pkgPOP.asMap(); ``` It returns me ``` Map<Integer, Collection<OccupancyType>> ``` How can I return `Map<Integer, Set<OccupancyType>>` instead ?

Original source