我希望在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分别是第一个键,第二个键和值的类型)
答案 0 :(得分:37)
您应该使用Map<Pair<K1,K2>, V>
它只包含一张地图 而不是N + 1地图
重点建设 将是显而易见的(创造 对)
没有人会对此感到困惑 地图的意义 面向API的程序员不会改变。
数据结构中的停留时间会更短,如果您发现需要稍后进行同步,这是很好的。
答案 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>