Java中的双向多值映射

Java中的双向多值映射,java,multimap,Java,Multimap,我正在寻找一种存储键值对的方法。我需要双向查找,但同时需要为同一个键存储多个值。换句话说,类似于BidiMap,但每个键都可以有多个值。例如,它需要能够容纳像“s1”->1,“s2”->1,“s3”->2这样的对,我需要能够得到映射到每个键的值,并且对于每个值,得到与它相关的所有键。希望我答对了 class A { long id; List<B> bs; } class B { long id; List<A> as; } A类{ 长

我正在寻找一种存储键值对的方法。我需要双向查找,但同时需要为同一个键存储多个值。换句话说,类似于BidiMap,但每个键都可以有多个值。例如,它需要能够容纳像“s1”->1,“s2”->1,“s3”->2这样的对,我需要能够得到映射到每个键的值,并且对于每个值,得到与它相关的所有键。

希望我答对了

class A {
    long id;
    List<B> bs;
}

class B {
    long id;
    List<A> as;
}
A类{
长id;
名单b;
}
B类{
长id;
列为;
}

有两个地图,键->值,值->键有什么不对?

我正使用谷歌的Guava MultiMap实现来实现这些目的

Map<Key Collection<Values>> 
Map
例如,其中集合可以是ArrayList。它允许将存储在集合中的多个值映射到一个键。
希望这有帮助

那么您需要支持多对多关系?你能得到的最接近的是@Mechkov写的——但更具体地说是
Multimap
与的组合。“BiMultimap”还没有实现,但Google Guava库中有此功能的请求

此时,您几乎没有选择:

  • 如果您的“双多重映射”是不可变常量,请使用
    Multimaps.invertFrom
    ImmutableMultimap
    /
    ImmutableListMultimap
    /
    ImmutableSetMultimap
    (这三者中的每一个都有不同的集合存储值)。一些代码(示例取自我开发的应用程序,使用
    Enum
    s和
    set.immutableEnumSet
    ):

    公共类角色和服务映射{
    私有静态最终不可变多重映射服务\u到\u角色\u映射=
    ImmutableMultimap.builder()
    .put(Service.SFP1、Authority.ROLE\u PREMIUM)
    .put(Service.SFP、Authority.ROLE\u PREMIUM)
    .put(Service.SFE、Authority.ROLE\u额外)
    .put(Service.SF、Authority.ROLE_标准)
    .put(Service.SK、Authority.ROLE_标准)
    .put(Service.SFP1,Authority.ROLE_ADMIN)
    .put(Service.ADMIN、Authority.ROLE\u ADMIN)
    .put(Service.NONE、Authority.ROLE\u DENY)
    .build();
    //整个魔法就在这里:
    私有静态最终ImmutableMultimap接口和实现类具有
    .inverse()
    方法,该方法在
    BiMap
    BiMap.inverse().inverse()
    之后提供
    BiMap
    视图和自身。如果我前面提到过,它可能会有类似的内容

  • (2016年10月编辑)您还可以使用以下文件中的内容:

    总体而言,common.graph支持以下种类的图形:

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

  • 我希望使用多值映射解决这个问题。 请在下面的链接中找到来自oracle的文档


    使用谷歌番石榴,我们可以编写一个原始的双模图,如下所示

    import java.util.Collection;
    
    import com.google.common.collect.ArrayListMultimap;
    import com.google.common.collect.Multimap;
    
    public class BiMultiMap<K,V> {
    
        Multimap<K, V> keyToValue = ArrayListMultimap.create();
        Multimap<V, K> 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<V> oldValue = keyToValue.get(key);
            if ( oldValue.contains(value) == false ) {
                keyToValue.put(key, value);
                valueToKey.put(value, key);
            }
        }
    
        public Collection<V> getValue(K key) {
            return keyToValue.get(key);
        }
    
        public Collection<K> getKey(V value) {
            return valueToKey.get(value);
        }
    
        @Override
        public String toString() {
            return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]";
        }
    
    }
    
    import java.util.Collection;
    导入com.google.common.collect.ArrayListMultimap;
    导入com.google.common.collect.Multimap;
    公共类双乘法映射{
    Multimap keyToValue=ArrayListMultimap.create();
    Multimap valueToKey=ArrayListMultimap.create();
    公共无效putForce(K键,V值){
    keyToValue.put(键,值);
    valueToKey.put(值,键);
    }
    公开作废认沽权(K键,V值){
    集合oldValue=keyToValue.get(键);
    if(oldValue.contains(value)==false){
    keyToValue.put(键,值);
    valueToKey.put(值,键);
    }
    }
    公共集合getValue(K键){
    返回keyToValue.get(key);
    }
    公共集合getKey(V值){
    返回valueToKey.get(值);
    }
    @凌驾
    公共字符串toString(){
    返回“BiMultiMap[keyToValue=“+keyToValue+”,valueToKey=“+valueToKey+””;
    }
    }
    
    希望这将有助于一些基本的双向多地图的需求。
    注意K和V需要正确地实现hascode和equals方法

    您谈到每个键需要有多个值,但在您的示例中,您没有包含多个值的键,而是一个包含两个键的值。您可能应该澄清这一点。如果您的示例适合您的问题,您将得到更好的答案;-)在这里您可以找到方法创造multimap@pushy,同样的问题,如果我反转映射,将整数保留为键而不是值,我将得到一对多映射。无论如何,感谢您的更正。:)我认为保留相同数据的两个副本更容易出错。无论如何,在我查看了所有集合之后,我开始认为它是最好的解决方案。只需为地图创建一个使其保持同步的包装器。我不喜欢这个答案所认可的方法。这有很多潜在的错误,包括可能重新发明轮子、编写自己的错误、线程安全等。这是一个接口。有实现吗?你太聪明了,不适合这样做我甚至不记得回答过这个问题
    import java.util.Collection;
    
    import com.google.common.collect.ArrayListMultimap;
    import com.google.common.collect.Multimap;
    
    public class BiMultiMap<K,V> {
    
        Multimap<K, V> keyToValue = ArrayListMultimap.create();
        Multimap<V, K> 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<V> oldValue = keyToValue.get(key);
            if ( oldValue.contains(value) == false ) {
                keyToValue.put(key, value);
                valueToKey.put(value, key);
            }
        }
    
        public Collection<V> getValue(K key) {
            return keyToValue.get(key);
        }
    
        public Collection<K> getKey(V value) {
            return valueToKey.get(value);
        }
    
        @Override
        public String toString() {
            return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]";
        }
    
    }