单值映射Java的多个键

时间:2011-07-20 21:47:50

标签: java data-structures map multidimensional-array

我认为我的问题类似于这个问题:How to implement a Map with multiple keys?但是有一个重要的区别。在那个问题中(如果我对它的理解是正确的,请告诉我,如果不是这样),键应该始终是唯一的。我希望在表单中有一个地图: 的 MyMap中 键不一定是唯一的。如果这没有意义,我基本上想要一个二维数组,而不是通过坐标引用元素,我想通过成对的对象来引用它们。

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

4 个答案:

答案 0 :(得分:18)

Guava中的Table数据结构似乎符合您通过一对对象引用值的要求。

答案 1 :(得分: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) {...}
}

hashcode方法将为所有包含元素生成哈希码(在本例中为两个,xy,但可以轻松扩展以支持任意数字如果xy具有相同的值,则两个键将相同。如果你的pair元素不是简单的字符串,那么派生几乎任何对象的字符串表示都是微不足道的(例如,提供toString方法的体面实现)。

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

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

public int hashcode() {
  return ('x' + x + ":y" + y).hashcode();
}

请务必提供一些分隔符。否则,对于x=ab, y=bx=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);
}

因此,现在您可以在地图中使用Pair课程,例如:

final Map<Pair, Whatever> map = new Hashmap<Pair, Whatever>();
// ...

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

如果您想在Pair中使用TreeMap课程,则必须实施compareTo方法,或在实例化此类地图时提供您自己的Comparator课程。 TreeMap实现依赖于compareTo方法的结果来确定应该在哪里分配值。

答案 2 :(得分:3)

Apache Commons Collections有MultiKey

import org.apache.commons.collections4.keyvalue.MultiKey;

Map<MultiKey, ValueType> myMap = new HashMap<MultiKey, ValueType>();
myMap.put(new MultiKey(key1, key2), value);

myMap.get(new MultiKey(key1, key2));

它具有从Map创建N维数组的好处。

答案 3 :(得分:2)

听起来我正在寻找一个嵌套的HashMap。这可能有用,但我的直觉说实施这样一个怪物将是一个可怕的想法,无论是表现明智还是理智。

如何初始化它:

    HashMap<Key1, HashMap<Key2, Value>> nestedHashMap = new HashMap<Key1, HashMap<Key2, Value>>();

添加值:

    Key1 first;
    Key2 second;
    Value data;
    HashMap<Key2, Value> tempMap = new HashMap<Key2, Value>();
    tempMap.put(second, data);
    nestedHashMap.put(first, tempMap);

获取数据:

    Key1 first;
    Key2 second;
    Value data;
    data = nestedHashMap.get(first).get(second);

免责声明:此代码尚未经过测试,它刚刚脱颖而出。