2011-07-29 24 views
8
public class Contact 
{ 
    int i; 
    String name; 
    public Contact(int iVal, String nameVal) 
    { 
     i = iVal; 
     name = nameVal; 
    } 
} 

public class MultiMap 
{ 
    public static void main (String args[]) 
    { 
     java.util.HashMap m = new java.util.HashMap(); 
       Contact m1 = new Contact(1, "name"); 
     Contact m2 = new Contact(1, "name"); 
     m.put(m1, "first"); 
     m.put(m2, "second"); 
     System.out.println(m.get(m1)); 
     System.out.println(m.get(m2)); 
    } 
} 

輸出是:對象爲不Hashcode方法映射鍵和等於

first 
second 

請問這個 「get」 方法的行爲?由於m1和M2具有相同的值,我沒有重寫hashcode(),Object類的equals()方法會被調用嗎?

這是正確的嗎?

  1. 沒有hashCode方法,所以沒有辦法讓JVM,看看對象M1和M2包含不同的值
  2. 沒有equals方法重寫所以Object類的equals()被調用,併爲這兩個對象是不同的代碼上面的工作正常沒有M2取代M1的價值。

回答

8

hashCode()equals(Object o)方法不受你的類中重寫時,爪哇只使用實際的參考對象在內存計算的值(即檢查它是否是類的同一個實例)。這就是爲什麼你仍然得到兩個結果。

0

這裏在Contact類中沒有實現hashcode()equals()函數。

當HashMap調用這些方法時,它將在父類中搜索出這些方法,在這種情況下它是Object。

在這種情況下,堆上的對象位置被評估而不是值。

例如對於兩個對象o1o2

o1.equals(o2) == true只有當o1 == o2

hashCode()是對象類的方法。散列碼是JVM對象的整數表示形式。哈希代碼是系統生成的,JVM以該對象的地址爲基礎(種子)來生成哈希代碼。對於不同的執行時間,生成的哈希代碼不需要相同。

0

是的,這是正確的。任何未定義自己的equals和hashcode方法的java對象都會繼承java.lang.Object上的默認equals和hascode方法。這些默認實現基於對象引用相等性,而不是邏輯相等。由於您使用相同的對象引用調用get,因此可以從地圖返回對象。

下面是一個例子,進一步說明這一點。

java.util.HashMap m = new java.util.HashMap(); 
Contact m1 = new Contact(1, "name"); 
Contact m2 = new Contact(1, "name"); 
m.put(m1, "first"); 
m.put(m2, "second"); 
System.out.println(m.get(m1));//first 
System.out.println(m.get(m2));//second 
System.out.println(m.get(new Contact(1, "name"));//null - since the new object has a different object reference. 
0

儘管m1和m2具有相同的值,但它們是不同的對象引用。

這是正確的: 沒有hashCode方法,所以沒有辦法讓JVM,看看對象M1和M2包含不同的值 - >所以它使用Object類的hasCode()方法來計算哈希碼值執行get(),它返回不同的哈希值(顯而易見)。

第二點也是正確的: 當你還沒有實現自己的equals(),會考慮對象的equals()方法返回,只有當一個對象進行比較,本身真正

2

它將使用對象類的equals和hashcode方法來查找值(因爲Contact不會覆蓋equals和hashcode方法),所以是的。

  1. 是,Java將總能看到兩個接觸對象是不同的,因爲它使用時equals方法的對象
  2. 是的,作爲兩個接觸對象都以引用將使用對象引用比較。
3

所有對象都有hashCode()和equals()。當它們不被覆蓋時,使用默認實現。默認行爲是將所有對象視爲不同的對象,除非它們是同一個對象。

爲了進行比較,即使您重寫了hashCode和equals,IdentityHashMap也會執行此操作。

0

默認情況下,Object類覆蓋hashCode和equals方法。這是您獲得理想輸出的原因。

如果不覆蓋equals和hashcode方法,JVM會在場景後面檢查它。由於m1和m2都是不同的對象實例,因此equals方法總是返回false。 即:

1.對於等於:因爲兩者都是不同的實例

m1.equals(平方米)//返回false。

2.對於的hashCode: //參見內HashMap.java源代碼

HashMap中內部使用投入HashMap中之前重新散列密鑰。見下圖。

[![Source code of put method][1]][1] 
public V put(K key, V value) { 
    return putVal(hash(key), key, value, false, true); 
} 

的翻版,HashMap具有它自己的靜態散列法:

[![Source code of hash method][1]][1] 
static final int hash(Object key) { 
     int h; 
     return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
    } 

內部,這樣既equals和hashCode方法的工作,那就是爲什麼你都存儲在HashMap中的值。

希望這會有所幫助:)