【问题标题】:What Java data structure is best for two-way multi-value mapping什么Java数据结构最适合双向多值映射
【发布时间】:2015-04-22 11:58:58
【问题描述】:

我对 Java 比较陌生,我对哪种类型的数据结构最适合我的情况有疑问。我有一组数据,它们本质上是键值对,但是每个值可能对应于多个键,每个键可能对应于多个值。一个简化的例子是:

  • 红苹果
  • 青苹果
  • 红草莓
  • 绿葡萄
  • 紫葡萄

考虑到上面的例子,我需要能够返回我有什么颜色的苹果和/或我有什么红色水果。实际数据将根据输入文件动态生成,其中每个集合将包含 100-100,000 个值,每个值可能对应于另一个集合中的数百个值。

存储和解析这些数据的最有效方法是什么?我更喜欢 Java 原生的解决方案,而不是外部数据库之类的解决方案。

This question 是相关的,但我不确定如何在我的情况下应用该解决方案,因为我需要在两个方向上为每个键分配多个值。

【问题讨论】:

标签: java dictionary data-structures bidirectional multivalue


【解决方案1】:

我建议你使用Guava's Table 结构。使用颜色作为行键,使用水果作为列键,反之亦然。具体来说,HashBasedTable 非常适合您的情况。

根据您的用例,您不需要为值存储任何内容。但是,这些 Tables 不允许 null 值。您可以使用虚拟 Boolean 或任何其他统计有用值,即插入日期和时间、用户、颜色/水果对的数量等。

Table有你需要的方法,如column()row()。请记住,文档说这些结构针对行访问进行了优化。如果您打算通过一个键而不是另一个键访问,这对您来说可能没问题。

【讨论】:

    【解决方案2】:

    您可以创建自己的自定义数据结构

    public class MultiValueHashMap<K, V> {
         private HashMap<K, ArrayList<V>> multivalueHashMap = new HashMap<K, ArrayList<V>>();
    
        public static void main(String[] args) {
            MultiValueHashMap<String, String> multivaluemap = new MultiValueHashMap<String, String>();
            multivaluemap.put("Red", "Apple");
            multivaluemap.put("Green", "Apple");
            multivaluemap.put("Red", "Strawberry");
            multivaluemap.put("Green", "Grapes");
            multivaluemap.put("Purple", "Grapes");
    
            for(String k : multivaluemap.keySet()){
                System.out.println(k + " : " + multivaluemap.get(k).toString());
            }
        }
    
        public void put(K key, V value){
            if (multivalueHashMap.containsKey(key)){
                ArrayList<V> values = multivalueHashMap.get(key);
                values.add(value);
            }else{
                ArrayList<V> values  = new ArrayList<V>();
                values.add(value);
                multivalueHashMap.put(key, values);
            }
        }
    
        public Set<K> keySet(){
            return multivalueHashMap.keySet();
        }
    
        public ArrayList<V> get(K key){
            return multivalueHashMap.get(key);
        }
    }
    

    输出应该是

    红色:[苹果、草莓]

    紫色:[葡萄]

    绿色:[苹果、葡萄]

    【讨论】:

      【解决方案3】:

      由于Map 中不能有重复的键,您可以创建一个Map&lt;Key, List&lt;Value&gt;&gt;,或者如果可以,使用Guava's Multimap

      Multimap<String, String> multimap = ArrayListMultimap.create();
      multimap.put("Red", "Apple");
      multimap.put("Red", "Strawberry");
      
      System.out.println(multimap.get("Red"));  // Prints - [Apple, Strawberry]
      

      但问题是你不能要求给定对象的键,如果我找到其他东西,我会继续寻找、制作和编辑,希望对你有所帮助。

      不过,您可以通过迭代地图并找到对象的键来自己进行逆向操作。

      【讨论】:

      • “但问题是您不能要求给定对象的键。” 听起来它可以通过 BiMultiMap 解决。不确定这是否存在,但这就是它的名称。或以节点名称为索引的有向图。
      • 你不能将其中两个包装在一个自定义对象中来实现这一点
      猜你喜欢
      • 2014-03-21
      • 2021-03-03
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      相关资源
      最近更新 更多