2011-02-14 56 views
5

我想用一個帶有2個分量的鍵實現一個HashMap。防爆。帶有2個鍵的Java集合

Pseudocode: 

Key = <Component1, Component2> 
CollName<Key, Val> coll = new CollName<Key, Val>; 

我該如何在Java中實現這一點,考慮到集合的速度和大小。謝謝:d

回答

7

你需要一個幫手(複合鍵)類,用於保存您的兩個鍵

public class CompositeKey<... , ...> { 
    ... component1; 
    ... component2; 

    // getter , setter, ... 

    // equals 

    // hashcode() 
} 

,然後你可以使用它作爲重點:

CompositeKey cKey = new CompositeKey(1,2); 
Map x.put(cKey,val); 

這是非常重要的在這裏以良好的方式實施equals()hashCode()。大多數IDE可以幫助你。重要的是,hashCode返回一個「唯一」值,以防止密鑰的哈希衝突(即,返回一個常數值是最糟糕的情況,因爲所有的值都會在同一個桶中結束)。哈希碼的許多實現做沿着

hashcode = component1.hashCode() + 37* component2.hashCode(); 

如果您想了解更多細節的東西,挖掘出任何CS的書,談到散列算法。

如果你想使用它作爲持久性,也可以看看this blog post

+0

@Hieko:本發明。你是否知道解釋助手類的來源,因爲我不熟悉這個概念。 – 2011-02-14 06:49:23

+1

輔助類不是一個特殊的概念,它只是一個普通的類,它包裝你的兩個子對象並將它們視爲一個對象。有關更詳細的代碼示例,請參閱下面的示例。 – 2011-02-14 06:51:58

2

您不能直接使用兩個鍵創建地圖,但可以將兩者結合使用。

最簡單的方法是將它們序列化爲一個字符串併合並它們。

String key = obj1.toString() + "-" + obj2.toString(); 
myMap.put(key, myValue); 

假定對象可以很容易地被序列化爲一個唯一的字符串。

如果不是這種情況,那麼創建一個包裝對象是最好的選擇。您需要定義一個覆蓋equals()和hashCode()方法的對象。

作一個粗略的例子

class CombinedKey{ 
    private MyClass object1; 
    private MyClass object2; 

    public CombinedKey(MyClass object1, MyClass object2){ 
     this.object1 = object1; 
     this.object2 = object2; 
    } 
    public int hashCode(){ 
     return object1.hashCode() + object2.hashCode(); 
    } 

    @Override 
    public Boolean equals(Object otherObject){ 
     if(otherObject == null || otherObject.getObject1() == null) return false; 
     return object1.equals(otherObject.getObject1()) && object2.equals(otherObject.getObject2(); 
    } 

    public MyClass getObject1() { return object1; } 
    public MyClass getObject2() { return object2; } 

} 

(您可能還需要考慮使用泛型來定義這個類,因此它可以在其他場景中重用)

用法:

Map<CombinedKey, Object> myMap = new HashMap<CombinedKey, Object>(); 
myMap.put(new CombinedKey(obj1, obj2), value); 
0

這是HashMap的常見用法,重點是您必須定義(覆蓋)等於()hashCode()Key正確。

0

使用CompositKey/Pair/Tuple的一個很好的選擇是使用ListList實現已經有一個正確定義的equals()hashCode()並且很容易使用Arrays.asList()