1. 程式人生 > >==、equals、hashcode的區別和聯絡

==、equals、hashcode的區別和聯絡

一、equals和==的區別

java中的資料型別,可分為兩類:
1.基本資料型別,也稱原始資料型別。byte,short,char,int,long,float,double,boolean
   他們之間的比較,應用雙等號(==),比較的是他們的值
2.複合資料型別(類)
   當他們用(==)進行比較的時候,比較的是他們在記憶體中的存放地址,所以,除非是同一個new出來的物件,他們的比較後的結果為true,否則比較後結果為false。JAVA當中所有的類都是繼承於Object這個基類的,在Object中的基類中定義了一個equals的方法,這個方法的初始行為是比較物件的記憶體地址,但在一些類庫當中這個方法被覆蓋掉了,如String,Integer,Date在這些類當中equals有其自身的實現,而不再是比較類在堆記憶體中的存放地址了。

   對於複合資料型別之間進行equals比較,在沒有覆寫equals方法的情況下,他們之間的比較還是基於他們在記憶體中的存放位置的地址值的,因為Object的equals方法也是用雙等號(==)進行比較的,所以比較後的結果跟雙等號(==)的結果相同。
 public class Object {
   ......
   public boolean equals(Object obj) {
        return (this == obj);
    }
}


 
二、equals和hashcode的區別

JDK對equals(Object obj)和hashcode()這兩個方法的定義和規範:
在Java中任何一個物件都具備equals(Object obj)和hashcode()這兩個方法,因為他們是在Object類中定義的。
equals(Object obj)方法用來判斷兩個物件是否“相同”,如果“相同”則返回true,否則返回false。
hashcode()方法返回一個int數,在Object類中的預設實現是“將該物件的內部地址轉換成一個整數返回”。

接下來有兩個個關於這兩個方法的重要規範(我只是抽取了最重要的兩個,其實不止兩個):
規範1:若重寫equals(Object obj)方法,有必要重寫hashcode()方法,確保通過equals(Object obj)方法判斷結果為true的兩個物件具備相等的hashcode()返回值。
說得簡單點就是:“如果兩個物件相同,那麼他們的hashcode應該 相等”。不過請注意:這個只是規範,如果你非要寫一個類讓equals(Object obj)返回true而hashcode()返回兩個不相等的值,編譯和執行都是不會報錯的。不過這樣違反了Java規範,程式也就埋下了BUG。
規範2:如果equals(Object obj)返回false,即兩個物件“不相同”,並不要求對這兩個物件呼叫hashcode()方法得到兩個不相同的數。說的簡單點就是:“如果兩個物件不相同,他們的hashcode可能相同”。

根據這兩個規範,可以得到如下推論:
1、如果兩個物件equals,Java執行時環境會認為他們的hashcode一定相等。
2、如果兩個物件不equals,他們的hashcode有可能相等。
3、如果兩個物件hashcode相等,他們不一定equals。
4、如果兩個物件hashcode不相等,他們一定不equals。

HashMap,也是先判斷hashcode再判斷equals,如果都相同,則表示:在集合新增中,認為是同一個"東西"。

HashSet的底層本身就是通過HashMap來實現的,所以他的判斷原理和HashMap是一樣的。

PS:
1、hashcode方法只有在集合中用到
2、將物件放入到集合中時,首先判斷要放入物件的hashcode值與集合中的任意一個元素的hashcode值是否相等,如果不相等直接將該物件放入集合中。如果hashcode值相等,然後再通過equals方法判斷要放入物件與集合中的任意一個物件是否相等,如果equals判斷不相等,直接將該元素放入到集合中,否則不放入。

    簡單來說,將物件放入到集合中時,就是先比較hashcode和後比較equals是否都相等

轉自:
http://www.cnblogs.com/zhxhdean/archive/2011/03/25/1995431
htmlhttp://blog.csdn.net/lclai/article/details/6195104
http://www.360doc.com/content/14/0527/09/15113968_381327452.shtml