有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

这是否有效(如果我没有添加到地图中,则不会抛出错误)?如果没有,我如何解决这个问题


共 (2) 个答案

  1. # 1 楼答案

    不,它无效,原因与将List<T>强制转换为List<Object>无效相同

    Multimap.asMap()返回一个视图according to the documentation。这意味着

    Multimap<K, V> multimap = ...;
    Map<SuperOfK, SuperOfV> map = (<some cast>) multimap.asMap();
    map.put(superOfK, superOfV);
    

    应该更新多重映射。虽然这本身不会导致ClassCastException,但像迭代键这样的操作会:

    for (K key : multimap.keys()) { }
    

    因此,这样的铸造是不安全的,所以是被禁止的

    当然,如果你的多重映射是不可变的,你就不会有这个问题,但这通常是你不应该这样做的原因。对编译器来说,说“我不会添加到映射”是不够的——它不知道你不会

  2. # 2 楼答案

    其他人已经回答了你的具体问题,但我认为你问错了问题(并且试图做一些你不应该做的事情)

    首先,我想问一下为什么您自己要实现Multimap。看来你可以避免那样做

    其次,您正试图使用map.putAll(Map)将传递给MultimapasMap()视图添加到Multimap.putAll(Multimap)实现中。这几乎肯定是错误的,并且会违反Multimap.putAll的规范。asMap()视图中的Collection值都是相关键的值的实时视图,当多重映射更改时,它们的内容将更改。如果您将这些集合直接添加到Map您可能有支持Multimap实现的Multimap中,那么如果随后修改了另一个Multimap,您的Multimap将最终更改。不仅如此,如果在Map中已经有该键的值,会发生什么