单值映射Java的多个键

Ste*_*eve 20 java map multidimensional-array data-structures

我认为我的问题与此类似:如何使用多个键实现Map?但有一个重要的区别.在那个问题中(如果我对它的理解是正确的,请告诉我,如果不是这样),键应该始终是唯一的.我希望在表单中有一个Map: MyMap ,其中键不一定是唯一的.如果这没有意义,我基本上想要一个二维数组,而不是通过坐标引用元素,我想通过成对的对象来引用它们.

任何人对这个有效的图书馆或自己实施的好方法都有任何想法吗?对于图书馆来说,我看过Apache Commons和Guava,似乎没有我想要的东西.

Mar*_*ark 19

Guava中的Table数据结构似乎满足了您通过一对对象引用值的要求.


cha*_*tle 13

我希望这个答案不会被视为咆哮,但据我所知,你想使用一个库,你可以用一个开箱即用的jdk以一种微不足道的方式实现.

无论如何,您提到要使用一对对象访问元素.您可以创建一个用于保存键的类,例如

public class Pair {
  // string represntation of an object
  private final String x; 
  private final String y;

  // ctor, getters...

  public int hashcode() {...}
  public boolean equals(Object other) {...}
}
Run Code Online (Sandbox Code Playgroud)

hashcode方法将产生所有包含的元素的哈希码(在这种情况下,两个,xy在你的情况,但可以很容易地扩展,以支持元件的任意数),和两个键将是相同的,如果它们具有相同的值xy.如果您对元素不是简单的字符串,它是微不足道的获得几乎任何对象的字符串表示(提供一个体面的实现的toString方法,例如).

我们的想法是为对中的每个元素提供唯一的字符串表示.

当然,生成实体哈希码并非易事,因此使用字符串是一个很好的选择.要生成哈希码,您只需附加对对象的字符串表示:

public int hashcode() {
  return ('x' + x + ":y" + y).hashcode();
}
Run Code Online (Sandbox Code Playgroud)

一定要提供一些分隔符.否则,对于诸如x=ab, y=b和的值x=a, y=bb,您将获得相同的哈希码,即使对象完全不同.

平等与检查对中元素的价值一样微不足道:

public boolean equals(Object other) {
  // if other is not null and is an instance of Pair
  final Pair otherPair = (Pair)other;
  return this.x.equals(otherPair.x) && this.y.equals(otherPair.y);
}
Run Code Online (Sandbox Code Playgroud)

所以,现在你可以Pair在地图中使用你的类,例如:

final Map<Pair, Whatever> map = new Hashmap<Pair, Whatever>();
// ...
Run Code Online (Sandbox Code Playgroud)

Basicaly,hashmap的工作原理是使用密钥的哈希码来确定应该在哪个桶中分配值.如果两个键具有相同的哈希码,则equals方法将用于确定是否刚发生冲突,或者它是否只是相同的键.

如果要Pair在a中使用类,TreeMap则必须实现该compareTo方法,或Comparator在实例化此类映射时提供自己的方法.TreeMap实现依赖于compareTo方法的结果来确定应该在何处分配值.

  • 我接受的答案是建议使用下面的Guava Table类,因为这似乎比编写/测试/调试我自己的自定义数据结构更容易.但是 - 仍然赞成平等优秀的解决方案,谢谢. (2认同)