如何使用Guava将MultiMap <Integer,Foo>转换为Map <Integer,Set <Foo >>?

bra*_*ter 10 java set guava

我正在使用Google Guava 12中的MultiMap,如下所示:

Multimap<Integer, OccupancyType> pkgPOP = HashMultimap.create();
Run Code Online (Sandbox Code Playgroud)

将值插入此multimap后,我需要返回:

Map<Integer, Set<OccupancyType>>
Run Code Online (Sandbox Code Playgroud)

但是,当我这样做时:

return pkgPOP.asMap();
Run Code Online (Sandbox Code Playgroud)

它归还给我

Map<Integer, Collection<OccupancyType>>
Run Code Online (Sandbox Code Playgroud)

我怎么能回来Map<Integer, Set<OccupancyType>>呢?

Xae*_*ess 19

看看这个问题并由 Guava dev负责人Kevin Bourrillion评论#2:

您可以将Map<K, Collection<V>>第一个转换为原始地图,然后再转换为Map<K, Set<V>>您想要的地图.您必须禁止未经检查的警告,此时您应该评论"安全,因为SetMultimap可以保证这一点." 我甚至可以更新SetMultimap javadoc以提及这个技巧.

所以不选择演员:

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

编辑:

从Guava 15.0开始,您可以使用帮助方法以更优雅的方式执行此操作:

Map<Integer, Set<OccupancyType>> mapOfSets = Multimaps.asMap(pkgPOP);
Run Code Online (Sandbox Code Playgroud)


Lou*_*man 10

番石榴贡献者:

做不安全的演员.这样会很安全.

Map<K, Set<V>>由于Java继承的工作方式,它无法返回.本质上,Multimap超类型必须返回一个Map<K, Collection<V>>,因为Map<K, Set<V>>不是子类型Map<K, Collection<V>>,你不能覆盖asMap()返回一个Map<K, Set<V>>.