java Guava:将多重映射转换为泛型超类型有效吗?
目前,我正在实现Multimap类,以允许使用multiset进行重复。特别是,我正在研究boolean putAll(Multimap<? extends K, ? extends V> multimap)
方法
我想这样做:
Map<K, Collection<V>> map = ((Multimap<K, V>)multimap).asMap();
其中asMap()
通常会返回一个Map<? extends K, Collection<? extends V>>
这是否有效(如果我没有添加到地图中,则不会抛出错误)?如果没有,我如何解决这个问题
# 1 楼答案
不,它无效,原因与将
List<T>
强制转换为List<Object>
无效相同Multimap.asMap()
返回一个视图according to the documentation。这意味着应该更新多重映射。虽然这本身不会导致
ClassCastException
,但像迭代键这样的操作会:因此,这样的铸造是不安全的,所以是被禁止的
当然,如果你的多重映射是不可变的,你就不会有这个问题,但这通常是你不应该这样做的原因。对编译器来说,说“我不会添加到映射”是不够的——它不知道你不会
# 2 楼答案
其他人已经回答了你的具体问题,但我认为你问错了问题(并且试图做一些你不应该做的事情)
首先,我想问一下为什么您自己要实现
Multimap
。看来你可以避免那样做其次,您正试图使用
map.putAll(Map)
将传递给Multimap
的asMap()
视图添加到Multimap.putAll(Multimap)
实现中。这几乎肯定是错误的,并且会违反Multimap.putAll
的规范。asMap()
视图中的Collection
值都是相关键的值的实时视图,当多重映射更改时,它们的内容将更改。如果您将这些集合直接添加到Map
您可能有支持Multimap
实现的Multimap
中,那么如果随后修改了另一个Multimap
,您的Multimap
将最终更改。不仅如此,如果在Map
中已经有该键的值,会发生什么