2012-05-28 113 views
2

我想創建一個具有某個類作爲鍵的映射。我碰到的問題是,因爲這個類包含指針,所以如果我使用HashMap(參見下面的代碼),則在散列時使用此地址。我怎樣才能得到它來比較實際值而不是地址,還是有一些其他的容器可以用來實現相同的結果?以對象作爲鍵的映射

import java.util.*; 
public class Main { 
    public static void main(String args[]) { 
     class Foo { 
      public Foo(String a) {s = a;} 
      public String s; 
     } 

     HashMap<Foo,Integer> a = new HashMap<Foo,Integer>(); 
     a.put(new Foo("test"), 1); 
     System.out.println(a.get(new Foo("test"))); 
    } 
} 

此輸出null

+0

您的問題標題不正確。你正在使用對象作爲鍵,而不是類。如果你使用類作爲鍵,那看起來像這樣:'HashMap a;'另外,dasblinkenlight是正確的。您需要在要用於映射鍵的對象的類中定義equals和hashcode。 – Bill

+0

謝謝,改了標題。 – howardh

回答

9

爲了使用一個類的實例,如您需要重寫它的hashCodeequals方法HashMap鍵。一旦你這樣做,一切都應該正常工作。

class Foo { 
    public Foo(String a) {s = a;} 
    public String s; 
    int hashCode() {return s.hashCode();} 
    boolean equals(Object other) { 
     if (other == this) return true; 
     if (!(other instanceof Foo)) return false; 
     return ((Foo)other).s.equals(s); 
    } 
} 
+0

對象的每個實例的哈希代碼是否必須是唯一的?我上面給出的例子只是一個簡單的例子,通常我還會有其他成員變量,所以有關這個哈希函數的任何建議? – howardh

+3

@howardh'hashCode'不需要是唯一的(實際上大多數情況下它不可能是唯一的),但它必須服從[hashcode/equals contract](http://docs.oracle.com/javase/) Java的1.4.2/docs/api/java/lang/Object.html#hashCode()) - 每次在同一對象上調用它時必須保持一致,並且對於相同的對象必須相同,但不一定是相反的方式(即具有相同散列碼的對象不必相同)。 – dasblinkenlight

+0

請注意「鑰匙」的可變性(本例中爲「s」字段)。至少,「關鍵」必須是不可變的才能正確使用關聯容器。詳細信息:[可變HashMap鍵是一種危險的做法嗎?](http://stackoverflow.com/questions/7842049/are-mutable-hashmap-keys-a-dangerous-practice)。 –

1

注意,你不能用類作爲主要的參數化Map,但實例類Foo。如果您使用的是類作爲地圖類型參數,它會是這樣的:

Map<Class<Foo>,Integer> map; 

瞭解,上面的是不是你的代碼的情況下,如果你需要的地圖一起工作的Foo實例:

Map<Foo,Integer> map; 

......然後,你需要確保Foo覆蓋bothequals()hashCode()一切工作正常。 Here's一篇不錯的文章解釋了你應該如何重寫這兩種方法。