2017-02-09 51 views
0
package com.sample; 

import java.util.HashMap; 

class Student{ 
    int id; 

    @Override 
    public int hashCode() { 
     return -1; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return false; // returning false 
    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Student s1=new Student(); 
     s1.id=123; 
     Student s2=new Student(); 
     s2.id=456; 

     HashMap<Student,String> s=new HashMap<Student,String>(); 


     s.put(s1, "One"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     s.put(s2, "Two"); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 
     s.put(s1, "Three"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 

     System.out.println("after insert"); 

     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 


    } 

} 



OUTPUT 

< s1 value > One < s1 hashcode > 79430 
< s2 value > Two < s2 hashcode > 84524 
< s1 value > Three < s1 hashcode > 80786814 
after insert 
< s1 value > Three < s1 hashcode > 80786814 //printing three for s1 
< s2 value > Two < s2 hashcode > 84524 //printing two for s2 

//現在,如果我們改變equals方法的返回類型爲true,輸出的變化無一不返回三個作爲輸出。我無法理解,如果我們改變equals方法的返回類型,爲什麼輸出會改變。請用bucket(HashMap)和equals方法的上下文來解釋。如果我們改變equals方法的返回值,爲什麼輸出會改變?

class Student{ 
    int id; 

    @Override 
    public int hashCode() { 
     return -1; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     return true; //returning true 
    } 

} 

public class MainClass { 

    public static void main(String[] args) { 
     Student s1=new Student(); 
     s1.id=123; 
     Student s2=new Student(); 
     s2.id=456; 

     HashMap<Student,String> s=new HashMap<Student,String>(); 


     s.put(s1, "One"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     s.put(s2, "Two"); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 
     s.put(s1, "Three"); 
     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 

     System.out.println("after insert"); 

     System.out.println(" < s1 value > "+s.get(s1) + " < s1 hashcode > "+s.get(s1).hashCode()); 
     System.out.println(" < s2 value > "+s.get(s2) + " < s2 hashcode > "+s.get(s2).hashCode()); 


    } 

} 


OUTPUT- 

< s1 value > One < s1 hashcode > 79430 
< s2 value > Two < s2 hashcode > 84524 
< s1 value > Three < s1 hashcode > 80786814 
after insert 
< s1 value > Three < s1 hashcode > 80786814 //printing three for s1 
< s2 value > Three < s2 hashcode > 80786814 //printing three for s2 
+0

請參考[爲什麼map使用equals方法檢查鍵](http://stackoverflow.com/questions/31860486/does-a-map-using-equals-method-for-key-checking-exists) –

回答

3

在你的第一個片段,你equals方法總是返回false,這意味着HashMap考慮所有Student情況下是唯一的。因此s.get(s1)s.get(s2)返回不同的值。

在你的第二個片段,你equals方法總是返回true和你hashCode總是返回-1,這意味着HashMap考慮所有Student實例是相同的。因此,s.get(s1)s.get(s2)都返回相同的值(每次調用put都會覆蓋先前的值)。值爲「三」,因爲這是您放入地圖的最後一個值(通過調用s.put(s1, "Three");)。

P.S.,印刷s.get(s1).hashCode()似乎毫無意義,因爲它是決定了該條目將被存儲在HashMap,而不是價值hashCode桶的關鍵(s1.hashCode())的hashCode

順便說一句,我起初感到驚訝,你的第一個片段不返回到s.get()所有呼叫null,因爲equals總是返回false,所以HashMap不應該能夠找到一個keyequal給定鍵。然而,檢查的HashMap源代碼,我發現鑰匙先用==相比equals之前被調用,這就是爲什麼HashMap可以找到你的鑰匙。

+0

嗨伊蘭, 我有一個懷疑,在第一個片段,當等於方法返回false。 首先,當我們都在做,s.put(S1,「一」),這將再次但是,當我們正在做s.put存儲HashMap中的值(S1,「三」),這是爲什麼更換價值,而不是拋出異常? –

+0

根據我的理解,當我們使用s.put(s1,「Three」)時,它將對密鑰執行散列並獲取桶索引並將該值存儲在該索引處。 現在,當我們正在做s.put(S1,「三」),它會在關鍵執行hasing並得到桶索引,它會比較與索引處的項鍵,則總是返回false平等方法被重寫,每次都返回false。 所以它應該有一個條目,但有一個相同的密鑰條目將違反hashmap屬性,這就是爲什麼它應該返回一個錯誤。 –

相關問題