我认为我的问题与这个问题类似:如何使用多个键实现Map? 但有一个重要的区别。在那个问题中(如果我理解正确,请让我知道如果不是),键应该始终是唯一的。我想要一个形式为: MyMap 的Map,其中键不一定是唯一的。如果这没有意义,我基本上想要一个二维数组,但不是通过坐标引用元素,而是通过对象对来引用它们。
有人有任何关于某个库适合这种需求或者自己实现它的好方法吗?就库而言,我已经看过Apache Commons和Guava,两者都似乎不符合我的要求。
我认为我的问题与这个问题类似:如何使用多个键实现Map? 但有一个重要的区别。在那个问题中(如果我理解正确,请让我知道如果不是),键应该始终是唯一的。我想要一个形式为: MyMap 的Map,其中键不一定是唯一的。如果这没有意义,我基本上想要一个二维数组,但不是通过坐标引用元素,而是通过对象对来引用它们。
有人有任何关于某个库适合这种需求或者自己实现它的好方法吗?就库而言,我已经看过Apache Commons和Guava,两者都似乎不符合我的要求。
Guava中的Table数据结构似乎符合您使用一对对象引用值的需求。
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
方法会为所有包含的元素(在此例中是两个元素x
和y
,但可以轻松扩展以支持任意数量的元素)生成哈希码。如果两个键具有相同的x
和y
值,则它们将是相同的。如果您的键值对元素不是简单字符串,则很容易派生出几乎任何对象的字符串表示(例如提供一个良好实现的toString
方法)。public int hashcode() {
return ('x' + x + ":y" + y).hashcode();
}
请确保提供一些分隔符。否则,对于像 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);
}
现在,你可以将你的 Pair
类用于映射中,例如:
final Map<Pair, Whatever> map = new Hashmap<Pair, Whatever>();
// ...
基本上,HashMap通过使用键的哈希码来确定值应分配到哪个存储桶中。如果两个键具有相同的哈希码,那么将使用equals方法来确定是发生了冲突还是它们是相同的键。
如果您想在TreeMap中使用您的Pair类,则必须实现compareTo方法或在实例化此类映射时提供自己的比较器。 TreeMap实现依赖于compareTo方法的结果来确定值应该分配到何处。
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维数组。
我觉得你在寻找一个嵌套的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);