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

牧云@^-^@ 提交于 2019-12-22 03:46:52

问题


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 ?


回答1:


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



回答2:


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>>.



来源:https://stackoverflow.com/questions/11204143/how-can-i-convert-multimapinteger-foo-to-mapinteger-setfoo-using-guava

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!