在java中使用二维键映射

时间:2011-06-16 14:21:07

标签: java hash map

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

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分别是第一个键,第二个键和值的类型)

7 个答案:

答案 0 :(得分:37)

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

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

  2. 重点建设 将是显而易见的(创造 对)

  3. 没有人会对此感到困惑 地图的意义 面向API的程序员不会改变。

  4. 数据结构中的停留时间会更短,如果您发现需要稍后进行同步,这是很好的。

答案 1 :(得分:15)

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

interface Table<R,C,V>
  

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

答案 2 :(得分:2)

我建议选择第二个选项

Map<Pair<K1,K2>,V>

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

如果你想要一个接口,那么你最初将你的Map<Pair<K1,K2>,V>用你自己的“DoubleKeyMap”包裹起来。

(并且不要忘记在Pair类中正确实现方法hash和equals !!)

答案 3 :(得分:1)

我会选择Map<Pair<K1,K2>, V>解决方案,因为:

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

答案 4 :(得分:1)

逻辑上,你对(key1,key2)对应某些东西,因为它是你地图的关键。因此,您可以考虑编写自己的类,其中包含K1和K2作为参数,并覆盖hashCode()方法(为了更方便,可以使用其他方法)。 这显然是解决问题的“干净”方式。

答案 5 :(得分:1)

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

稍微搜索一下,我发现this post可能对您有用。特别是,在Apache Commons Collection中,MultiKeyMap。我之前从未使用过它,但它看起来像是一个不错的解决方案,可能值得探索。

答案 6 :(得分:-1)

我使用数组作为密钥:像这样

Map<Array[K1,K2], V>