JAVA基礎(一)equals和==和hashCode

magic_dreamer發表於2010-06-07
JAVA基礎(一)equals和==和hashCode

根據網上內容摘錄

堆(heap)和棧(stack)的區別
堆儲存: heapstorage 堆儲存分配: heapstorage allocation 堆儲存管理: heap storage management
棧編址: stack addressing 棧變換:stack transformation 棧儲存器:stack memory 棧單元: stack cell

Heap(堆) Stack(棧)
JVM中的功能 記憶體資料區 記憶體指令區
儲存資料 物件例項(1) 基本資料型別, 指令程式碼,常量,物件的引用地址(2)

(1).
儲存物件例項,實際上是儲存物件例項的屬性值,屬性的型別和物件本身的型別標記等,並不儲存物件的方法(方法是指令,儲存在stack中)。

物件例項在heap中分配好以後,需要在stack中儲存一個4位元組的heap記憶體地址,用來定位該物件例項在heap中的位置,便於找到該物件例項

(2).
基本資料型別包括byte、int、char、long、float、double、boolean和short。函式方法屬於指令.

JAVA中的== equals hashcode問題
1. '=='是用來比較兩個變數(基本型別和物件型別)的值是否相等的, 如果兩個變數是基本型別的,那很容易,直接比較值就可以了。如果兩個變數是物件型別的,那麼它還是比較值,只是它比較的是這兩個物件在棧中的引用(即地址)。
物件是放在堆中的,棧中存放的是物件的引用(地址)。由此可見'=='是對棧中的值進行比較的。如果要比較堆中物件的內容是否相同,那麼就要重寫equals方法了。

2. Object類中的equals方法就是用'=='來比較的,所以如果沒有重寫equals方法,equals和==是等價的。
通常我們會重寫equals方法,讓equals比較兩個物件的內容,而不是比較物件的引用(地址)因為往往我們覺得比較物件的內容是否相同比比較物件的引用(地址)更有意義。

3. Object類中的hashCode是返回物件在記憶體中地址轉換成的一個int值(可以就當做地址看)。所以如果沒有重寫hashCode方法,任何物件的hashCode都是不相等的。通常在集合類的時候需要重寫hashCode方法和equals方法,因為如果需要給集合類(比如:HashSet)新增物件,那麼在新增之前需要檢視給集合裡是否已經有了該物件,比較好的方式就是用hashCode

4. 注意的是String、Integer、Boolean、Double等這些類都重寫了equals和hashCode方法,這兩個方法是根據物件的內容來比較和計算hashCode的。(詳細可以檢視jdk下的String.java原始碼),所以只要物件的基本型別值相同,那麼hashcode就一定相同。

5. equals()相等的兩個物件,hashcode()一般是相等的,最好在重寫equals()方法時,重寫hashcode()方法; equals()不相等的兩個物件,卻並不能證明他們的hashcode()不相等。換句話說,equals()方法不相等的兩個物件,hashcode()有可能相等。 反過來:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。在object類中,hashcode()方法是本地方法,返回的是物件的引用(地址值),而object類中的equals()方法比較的也是兩個物件的引用(地址值),如果equals()相等,說明兩個物件地址值也相等,當然hashcode()也就相等了。
以下是測試程式碼。
《Effective Java》中也提到重寫equal方法,規範性地也需要重寫hashCode()。

重寫該方法,影響m1.equals(m2)
public boolean equals(Object o){
return true;
}

重寫該方法,影響m1.hashCode()和m2.hashCode()的輸出
public int hashCode(){
return 111;
}

另外,當hashCode不等的時候,向HashMap中存放值
Map map = new HashMap();
map.put(m1, m1);
map.put(m2, m2);
System.out.println(map.size());
System.out.println(map.containsKey(m1));
System.out.println(map.containsKey(m2));
會放入2個,就算equals是true
如果hashCode相等,會存放入1個:)

相關文章