Java中的双向多值映射

Boj*_*ska 19 java multimap

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

Xae*_*ess 22

那么你需要支持多对多的关系吗?最近可以得到的是番石榴Multimap像@Mechkov写了-但更具体Multimap结合Multimaps.invertFrom."BiMultimap"尚未实现,但在Google Guava库中请求此功能存在问题.

此时您几乎没有选择:

  1. 如果您的"BiMultimap"将变为不可变常量 - 使用Multimaps.invertFromImmutableMultimap/ ImmutableListMultimap/ ImmutableSetMultimap(每个三个具有不同的集合存储值).一些代码(从我开发的应用程序中获取的示例,使用Enums和Sets.immutableEnumSet):

    public class RolesAndServicesMapping {
        private static final ImmutableMultimap<Service, Authority> SERVICES_TO_ROLES_MAPPING = 
             ImmutableMultimap.<Service, Authority>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<Authority, Service> ROLES_TO_SERVICES_MAPPING =
                SERVICES_TO_ROLES_MAPPING.inverse();
        // before guava-11.0 it was: ImmutableMultimap.copyOf(Multimaps.invertFrom(SERVICES_TO_ROLES_MAPPING, HashMultimap.<Authority, Service>create()));
    
        public static ImmutableSet<Authority> getRoles(final Service service) {
            return Sets.immutableEnumSet(SERVICES_TO_ROLES_MAPPING.get(service));
        }
    
        public static ImmutableSet<Service> getServices(final Authority role) {
            return Sets.immutableEnumSet(ROLES_TO_SERVICES_MAPPING.get(role));
        }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 如果你真的希望你的Multimap可以修改,那么很难同时维护K-> V和V-> K变体,除非你只是修改kToVMultimap并且invertFrom每次想要反转副本时调用(并且使该副本不可修改)确保你不小心不修改vToKMultimap不会更新的内容kToVMultimap.这不是最佳的,但在这种情况下应该这样做.

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

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

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

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