Java中的双向多值映射 [英] Bidirectional multi-valued map in Java

查看:144
本文介绍了Java中的双向多值映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am looking for a way to store key-value pairs. I need the lookup to be bidirectional, but at the same time I need to store multiple values for the same key. In other words, something like a BidiMap, but for every key there can be multiple values. For example, it needs to be able to hold pairs like: "s1"->1, "s2"->1, "s3"->2, and I need to be able to get the value mapped to each key, and for each value, get all the keys associated with it.

推荐答案

所以你需要支持多对多关系?最近的是番石榴 Multimap 喜欢@Mechkov写道 - 但更具体地说是 Multimap Multimaps.invertFrom 。 BiMultimap尚未实施,但有问题在Google Guava库中请求此功能。

So you need support for many-to-many relationships? Closest you can get is Guava's Multimap like @Mechkov wrote - but more specifically Multimap combination with Multimaps.invertFrom. "BiMultimap" isn't implemented yet, but there is an issue requesting this feature in Google Guava library.

此时您几乎没有选择:


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

  1. If your "BiMultimap" is going to immutable constant - use Multimaps.invertFrom and ImmutableMultimap / ImmutableListMultimap / ImmutableSetMultimap (each of theese three has different collection storing values). Some code (example taken from app I develop, uses Enums and 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));
    }
}


  • 如果你真的想让你的Multimap成为可修改的,除非你只修改 kToVMultimap 并调用 invertFrom ,否则很难保持K-> V和V-> K变体code>每次你想要它的反转副本(并使该副本不可修改,以确保你不小心不修改 vToKMultimap 什么不会更新 kToVMultimap )。这不是最佳的,但在这种情况下应该这样做。

  • If you really want your Multimap to be modifiable, it will be hard to maintain both K->V and V->K variants unless you will be modifying only kToVMultimap and call invertFrom each time you want to have its inverted copy (and making that copy unmodifiable to make sure that you accidentally don't modify vToKMultimap what wouldn't update kToVMultimap). This is not optimal but should do in this case.

    (可能不是你的情况,作为奖金提到): BiMap 接口和实现类具有 .inverse()方法,该方法提供 BiMap< V,K> biMap.inverse()。inverse()之后从 BiMap< K,V> 查看。如果我之前提到的此问题已完成,则可能会有类似的东西。

    (Not your case probably, mentioned as bonus): BiMap interface and implementing classes has .inverse() method which gives BiMap<V, K> view from BiMap<K, V> and itself after biMap.inverse().inverse(). If this issue I mentioned before is done, it will probably have something similar.

    (2016年10月编辑)您也可以使用新图形API 将出现在 Guava 20

    (EDIT October 2016) You can also use new graph API which will be present in Guava 20:


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

    As a whole, common.graph supports graphs of the following varieties:


    • 有向图

    • 无向图

    • 具有关联值(权重,标签等)的节点和/或边缘

    • 允许/不允许的图形自循环

    • 允许/不允许平行边的图(具有平行边的图有时称为多图)

    • 其节点/边缘是插入排序,排序或无序的图形
    • directed graphs
    • undirected graphs
    • nodes and/or edges with associated values (weights, labels, etc.)
    • graphs that do/don't allow self-loops
    • graphs that do/don't allow parallel edges (graphs with parallel edges are sometimes called multigraphs)
    • graphs whose nodes/edges are insertion-ordered, sorted, or unordered


  • 这篇关于Java中的双向多值映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆