【问题标题】:Map with two-dimensional key in javajava中带有二维键的映射
【发布时间】:2011-09-16 10:29:27
【问题描述】:

我想要一个由 Java 中的两个键索引的映射(一个您使用两个键放置和检索值的映射)。为了清楚起见,我正在寻找以下行为:

map.put(key1, key2, value); 
map.get(key1, key2); // returns value
map.get(key2, key1); // returns null
map.get(key1, key1); // returns null

最好的方法是什么?更具体地说,我应该使用:

  • Map<K1,Map<K2,V>>

  • Map<Pair<K1,K2>, V>

  • 其他?

(其中K1,K2,V分别是第一个key、第二个key和value的类型)

【问题讨论】:

  • 你不能只有一个由两个值组成的键吗?
  • @Adrian:这不是Map<Pair<K1,K2>, V> 会做的吗?从技术上讲,只有一个键,但它包含两个值。
  • @Adrian 是的,我的第二个选择就是这个意思

标签: java hash map


【解决方案1】:

你应该使用Map<Pair<K1,K2>, V>

  1. 它只会包含一张地图, 而不是 N+1 个地图

  2. 密钥构造 将是显而易见的(创建 对)

  3. 没有人会混淆 地图的意义 面向程序员的 API 不会改变。

  4. 数据结构中的驻留时间会更短,如果您以后发现需要同步它,这很好。

【讨论】:

  • 我正在使用“apache commons”库。有谁知道“配对”课程是否有效? (我的意思是,如果它实现了 hashCode 并且在这种情况下正确地等于?)
  • 哈希不需要完美,一个好方法是实现你自己的对。 hashcode() 方法可以只返回 a.hashCode() xor b.hashCode()。
  • 但是每次我们在 doubleMap 中搜索某些东西时,这不就是为一对对象分配内存吗?我的意思是,它更简洁,但如果我们谈论的是带有静态数据的大地图,这个解决方案是不是在内存设计方面做得不好?
  • 如果您担心每次搜索时分配,您使用哪种地图并不重要,因为地图并不是真正的核心问题。您可能希望工厂生成支持唯一密钥存储的密钥,以便生成两个密钥的两个请求两次返回相同的对象。它独立于 Map of pair 问题,而且 Map of Maps 可能会占用更多存储空间,考虑到哈希数组(1 对 1*M,在 M*N 示例中)和桶列表,它们都必须维护。
【解决方案2】:

我使用数组作为键:像这样

Map<Array[K1,K2], V>

【讨论】:

    【解决方案3】:

    虽然我也同意您提出的建议(一对用作键的值),但您也可以考虑制作一个可以保存/匹配两个键的包装器。这可能会有点令人困惑,因为您需要重写 equals 和 hashCode 方法并使其工作,但这可能是一种直接的方式,可以向使用您的代码的下一个人指示键必须是特殊类型。

    搜索了一下,我找到了this post,这可能对你有用。特别是,在 Apache Commons Collection 中,MultiKeyMap。我以前从未使用过它,但它看起来是一个不错的解决方案,可能值得探索。

    【讨论】:

      【解决方案4】:

      如果您愿意引入一个新库(我推荐),请查看Guava 中的Table。这基本上完全符合您的要求,还可能添加一些功能,您可能希望所有条目与您的两个键之一匹配。

      interface Table<R,C,V>
      

      关联一个集合 有序键对,称为行键 和一个列键,具有单个值。 一个表可能是稀疏的,只有一个 行键/列键的一小部分 具有对应的对 价值。

      【讨论】:

      【解决方案5】:

      从逻辑上讲,您的 Pair (key1, key2) 对应于 something,因为它是您地图的键。因此,您可以考虑编写自己的类,将 K1 和 K2 作为参数并覆盖 hashCode() 方法(为了更方便,可能还加上其他方法)。 这显然是解决问题的“干净”方式。

      【讨论】:

        【解决方案6】:

        我建议选择第二个选项

        Map<Pair<K1,K2>,V>
        

        第一个在检索数据时会产生更多的过载,在从 Map 中插入/删除数据时会产生更多的过载。每次你放一个新的Value V,你需要检查K1的Map是否存在,如果不存在,创建它并把它放在主Map中,然后把值和K2一起放。

        如果您想在公开时有一个界面,最初用您自己的“DoubleKeyMap”包装您的Map&lt;Pair&lt;K1,K2&gt;,V&gt;

        (别忘了在Pair类中正确实现hash和equals方法!!)

        【讨论】:

          【解决方案7】:

          我会选择Map&lt;Pair&lt;K1,K2&gt;, V&gt; 解决方案,因为:

          • 它直接表达了你想做什么
          • 可能更快,因为它使用的间接更少
          • 简化了客户端代码(后面使用Map的代码

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-11-22
            • 1970-01-01
            • 2010-12-13
            • 1970-01-01
            • 1970-01-01
            • 2020-05-13
            • 2012-07-02
            相关资源
            最近更新 更多