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 ?
A Multimap is a new collection type that is found in Google's Guava library for Java. A Multimap can store more than one value against a key. Both the keys and the values are stored in a collection, and considered to be alternates for Map<K, List<V>> or Map<K, Set<V>> (standard JDK Collections Framework).
Stores a collection of values with the same key, replacing any existing values for that key. If values is empty, this is equivalent to removeAll(key) . Because a SetMultimap has unique values for a given key, this method returns a Set , instead of the Collection specified in the Multimap interface.
MultiHashMap is the default implementation of the MultiMap interface. A MultiMap is a Map with slightly different semantics. Putting a value into the map will add the value to a Collection at that key. Getting a value will return a Collection, holding all the values put to that key.
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 theMap<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);
Guava contributor here:
Do the unsafe cast. It'll be safe.
It can't return a Map<K, Set<V>>
because of the way Java inheritance works. Essentially, the Multimap
supertype has to return a Map<K, Collection<V>>
, and because Map<K, Set<V>>
isn't a subtype of Map<K, Collection<V>>
, you can't override asMap()
to return a Map<K, Set<V>>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With