Java中的双向多值映射

我正在寻找一种存储键值对的方法。 我需要查找是双向的,但同时我需要为同一个密钥存储多个值。 换句话说,比如BidiMap,但对于每个键,可以有多个值。 例如,它需要能够保存对,如:“s1” – > 1,“s2” – > 1,“s3” – > 2,我需要能够获取映射到每个键的值,并且对于每个值,获取与其关联的所有键。

那么你需要支持多对多关系吗? 最接近的是像@Mechkov写的番石榴的多图,但更具体地说是MultimapMultimaps.invertFrom组合。 “BiMultimap”尚未实现,但在Google Guava库中请求此function时出现问题 。

此时您几乎没有选择:

  1. 如果你的“BiMultimap”是不可变的常量 – 使用Multimaps.invertFromImmutableMultimap / ImmutableListMultimap / ImmutableSetMultimap (每个theese三个都有不同的集合存储值)。 一些代码(从我开发的应用程序中获取的示例,使用EnumSets.immutableEnumSet ):

     public class RolesAndServicesMapping { private static final ImmutableMultimap SERVICES_TO_ROLES_MAPPING = ImmutableMultimap.builder() .put(Service.SFP1, Authority.ROLE_PREMIUM) .put(Service.SFP, Authority.ROLE_PREMIUM) .put(Service.SFE, Authority.ROLE_EXTRA) .put(Service.SF, Authority.ROLE_STANDARD) .put(Service.SK, Authority.ROLE_STANDARD) .put(Service.SFP1, Authority.ROLE_ADMIN) .put(Service.ADMIN, Authority.ROLE_ADMIN) .put(Service.NONE, Authority.ROLE_DENY) .build(); // Whole magic is here: private static final ImmutableMultimap ROLES_TO_SERVICES_MAPPING = SERVICES_TO_ROLES_MAPPING.inverse(); // before guava-11.0 it was: ImmutableMultimap.copyOf(Multimaps.invertFrom(SERVICES_TO_ROLES_MAPPING, HashMultimap.create())); public static ImmutableSet getRoles(final Service service) { return Sets.immutableEnumSet(SERVICES_TO_ROLES_MAPPING.get(service)); } public static ImmutableSet getServices(final Authority role) { return Sets.immutableEnumSet(ROLES_TO_SERVICES_MAPPING.get(role)); } } 
  2. 如果你真的希望你的Multimap可以修改,那么很难同时维护K-> V和V-> K变体,除非你每次只想修改kToVMultimap并调用invertFrom你想要它的反转副本(并且复制不可修改,以确保您不小心不修改vToKMultimap什么不会更新kToVMultimap )。 这不是最佳的,但在这种情况下应该这样做。

  3. (可能不是你的情况,作为奖励提到): BiMap接口和实现类具有.inverse()方法,它在biMap.inverse().inverse()之后从BiMap和它自身给出BiMap视图biMap.inverse().inverse() 。 如果我之前提到的这个问题已经完成,它可能会有类似的东西。

  4. (2016年10月编辑)您还可以使用将在Guava 20中出现的新图API :

    作为一个整体,common.graph支持以下类型的图表:

    • 有向图
    • 无向图
    • 节点和/或具有相关值的边(权重,标签等)
    • 允许/不允许自循环的图形
    • 允许/不允许平行边的图(具有平行边的图有时称为多图)
    • 节点/边是插入排序,排序或无序的图

有两个地图,键 – >值,值 – >键有什么问题?

我希望使用MultivaluedMap解决问题。 请在下面的链接中找到oracle的文档。

http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/MultivaluedMap.html

使用Google Guava,我们可以编写一个原始的BiMulitMap,如下所示。

 import java.util.Collection; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; public class BiMultiMap { Multimap keyToValue = ArrayListMultimap.create(); Multimap valueToKey = ArrayListMultimap.create(); public void putForce(K key, V value) { keyToValue.put(key, value); valueToKey.put(value, key); } public void put(K key, V value) { Collection oldValue = keyToValue.get(key); if ( oldValue.contains(value) == false ) { keyToValue.put(key, value); valueToKey.put(value, key); } } public Collection getValue(K key) { return keyToValue.get(key); } public Collection getKey(V value) { return valueToKey.get(value); } @Override public String toString() { return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]"; } } 

希望这将有助于双向多地图的一些基本需求。 注意K和V需要正确实现hascode和equals方法

希望我帮到你

 class A { long id; List bs; } class B { long id; List as; } 

谷歌的Guava MultiMap实现就是我用于这些目的的。

 Map> 

例如,Collection可以是ArrayList。 它允许将存储在集合中的多个值映射到键。 希望这可以帮助!