JAVA基礎(一)equals和==和hashCode
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個:)
根據網上內容摘錄
堆(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個:)
相關文章
- Java基礎- ==和equals和hashCode的區別Java
- Java基礎系列-equals方法和hashCode方法Java
- 『Java 語法基礎』對 equals() 和 hashCode() 的理解Java
- java~重寫hashcode和equalsJava
- 搞懂 Java equals 和 hashCode 方法Java
- Java中hashcode和equals效能注意點 - ShaiJavaAI
- String的equals和hashCode方法
- java自定義equals函式和hashCode函式Java函式
- java為什麼要重寫hashCode和equals方法Java
- 自動生成hashcode和equals方法
- [Java基礎]HashcodeJava
- hashCode()和equals()的區別?(skycto JEEditor)
- 關於equals()和hashcode()的一些約定
- 關於重寫equals()和hashCode()的思考
- equals & hashCode
- 物件只定義了Equals和Hashcode方法之一的漏洞物件
- Java 基礎:解析 hashCodeJava
- hashCode()與equals()
- equals&hashCode
- 從語言設計的角度探究Java中hashCode()和equals()的關係Java
- ==、equals、hashcode總結
- 關於HashMap的key重寫hashcode和equals的理解HashMap
- Java equals和==完全解析Java
- Java equals 和 == 完全解析Java
- DDD實體值物件的equals和hashcode方法實現 - wimdeblauwe物件
- 【Java】equals 和 == 的區別Java
- Java備忘錄《“==” 和 “equals”》Java
- equals與hashCode關係梳理
- java 中equals和==的區別Java
- “==”、“equals()”、“hashcode()”之間的祕密
- Hashcode相同但是equals不同的例子
- equals 和 ==
- Java基礎-- ==號與equals()方法的區別Java
- Java基礎| 類和物件Java物件
- java 中為什麼重寫 equals 後需要重寫 hashCodeJava
- 一,認識計算機和Java基礎計算機Java
- Java中 equals() 方法和 == 的區別Java
- 從原始碼探究JAVA的equals和==原始碼Java
- 看似簡單的hashCode和equals面試題,竟然有這麼多坑!面試題