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

14

我正在使用Google Guava 12的MultiMap,像这样:

Multimap<Integer, OccupancyType> pkgPOP = HashMultimap.create();

在将值插入到此多映射中后,我需要返回:

Map<Integer, Set<OccupancyType>>

不过,当我执行以下操作:

return pkgPOP.asMap();

它返回给我

Map<Integer, Collection<OccupancyType>>

如何返回 Map<Integer, Set<OccupancyType>>

2个回答

23
请查看由Guava的首席开发人员Kevin Bourrillion在这个问题的评论#2:

您可以先将Map<K,Collection<V>>双重转换为原始Map,然后再转换为所需的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();

编辑:

自Guava 15.0版本以来,您可以使用helper method以更优雅的方式进行此操作:

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

1
我确信最右边的转换必须是普通的“Map”,但也许那是由于我们不再关心的javac版本...不确定。 - Kevin Bourrillion

10

我是Guava的贡献者:

进行不安全类型转换。这将是安全的。

由于Java继承的工作原理,它无法返回Map<K,Set<V>>。基本上,Multimap的超类型必须返回Map<K,Collection<V>>,而因为Map<K,Set<V>>不是Map<K,Collection<V>>的子类型,你无法重写asMap()以返回Map<K,Set<V>>


路易斯,你一点都不睡觉,是吗?;) - Grzegorz Rożniecki
在编程中,我使用(Set)MultiMap的实现是否重要?(在我的情况下,我正在使用HashMultiMap)。如果我像这样使用SetMultiMap mapOfSets = LinkedListMultiMap.create(),会发生什么问题吗? - brainydexter
好的,“LinkedListMultimap”是一个“ListMultimap”,而不是“SetMultimap”。只要您使用一些“SetMultimap”实现,例如“LinkedHashMultimap”或“TreeMultimap”,那么就没问题了。(@Xaerxess,我在整个夏天都在英国时间上工作。) - Louis Wasserman
@LouisWasserman 谢谢!你和Xaerxess的回答都对我很有帮助。 - brainydexter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接