why在重寫(xiě)equals時(shí)還必須重寫(xiě)hashcode方法分享
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
那為什么在重寫(xiě)equals方法時(shí)都要重寫(xiě)equals方法呢:
首先equals與hashcode間的關(guān)系是這樣的:
1、如果兩個(gè)對(duì)象相同(即用equals比較返回true),那么它們的hashCode值一定要相同;
2、如果兩個(gè)對(duì)象的hashCode相同,它們并不一定相同(即用equals比較返回false)
自我的理解:由于為了提高程序的效率才實(shí)現(xiàn)了hashcode方法,先進(jìn)行hashcode的比較,如果不同,那沒(méi)就不必在進(jìn)行equals的比較了,這樣就大大減少了equals比較的
次數(shù),這對(duì)比需要比較的數(shù)量很大的效率提高是很明顯的,一個(gè)很好的例子就是在集合中的使用;
我們都知道java中的List集合是有序的,因此是可以重復(fù)的,而set集合是無(wú)序的,因此是不能重復(fù)的,那么怎么能保證不能被放入重復(fù)的元素呢,但靠equals方法一樣比較的
話(huà),如果原來(lái)集合中以后又10000個(gè)元素了,那么放入10001個(gè)元素,難道要將前面的所有元素都進(jìn)行比較,看看是否有重復(fù),歐碼噶的,這個(gè)效率可想而知,因此hashcode
就應(yīng)遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是將對(duì)象數(shù)據(jù)根據(jù)該對(duì)象的特征使用特定的算法將其定義到一個(gè)地址上,那么在后面定義進(jìn)來(lái)的數(shù)據(jù)
只要看對(duì)應(yīng)的hashcode地址上是否有值,那么就用equals比較,如果沒(méi)有則直接插入,只要就大大減少了equals的使用次數(shù),執(zhí)行效率就大大提高了。
繼續(xù)上面的話(huà)題,為什么必須要重寫(xiě)hashcode方法,其實(shí)簡(jiǎn)單的說(shuō)就是為了保證同一個(gè)對(duì)象,保證在equals相同的情況下hashcode值必定相同,如果重寫(xiě)了equals而未重寫(xiě)
hashcode方法,可能就會(huì)出現(xiàn)兩個(gè)沒(méi)有關(guān)系的對(duì)象equals相同的(因?yàn)閑qual都是根據(jù)對(duì)象的特征進(jìn)行重寫(xiě)的),但hashcode確實(shí)不相同的
- java中hashCode方法與equals方法的用法總結(jié)
- 詳解hashCode()和equals()的本質(zhì)區(qū)別和聯(lián)系
- 重寫(xiě)hashCode()和equals()方法詳細(xì)介紹
- JAVA hashCode使用方法詳解
- 詳解Java中用于查找對(duì)象哈希碼值的hashCode()函數(shù)
- 為什么在重寫(xiě) equals方法的同時(shí)必須重寫(xiě) hashcode方法
- java 中HashCode重復(fù)的可能性
- javascript中實(shí)現(xiàn)兼容JAVA的hashCode算法代碼分享
- 重新實(shí)現(xiàn)hashCode()方法
相關(guān)文章
IDEA 2020.3 更新了機(jī)器學(xué)習(xí)都整上了
IDEA 歡迎窗口全新升級(jí),首頁(yè)增加三個(gè)選項(xiàng)卡,一個(gè)用于設(shè)置 IDE 界面的 Customize,一個(gè)用于插件安裝的 Plugins,一個(gè)于訪(fǎng)問(wèn)幫助和學(xué)習(xí)資源的 Learn IntelliJ IDEA,另外包括之前用于管理項(xiàng)目的 Projects,需要的朋友可以參考下2020-12-12
java?MultipartFile文件上傳重命名詳細(xì)代碼示例
在文件上傳功能開(kāi)發(fā)中,為防止文件重名導(dǎo)致數(shù)據(jù)覆蓋,常見(jiàn)的做法是在文件名前加上UUID或時(shí)間戳來(lái)區(qū)分,這篇文章主要介紹了java?MultipartFile?multipartFile文件上傳重命名的相關(guān)資料,需要的朋友可以參考下2024-09-09
Spring與Mybatis相結(jié)合實(shí)現(xiàn)多數(shù)據(jù)源切換功能
這篇文章主要介紹了Spring與Mybatis相結(jié)合實(shí)現(xiàn)多數(shù)據(jù)源切換功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06
Java設(shè)計(jì)模式之代理模式與@Async異步注解失效的解決
代理模式是Java常見(jiàn)的設(shè)計(jì)模式之一。所謂代理模式是指客戶(hù)端并不直接調(diào)用實(shí)際的對(duì)象,而是通過(guò)調(diào)用代理,來(lái)間接的調(diào)用實(shí)際的對(duì)象2022-07-07
java Swing基礎(chǔ)教程之圖形化實(shí)例代碼
這篇文章主要介紹了java Swing基礎(chǔ)教程之圖形化實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02
Java實(shí)現(xiàn)拖拽文件上傳dropzone.js的簡(jiǎn)單使用示例代碼
本篇文章主要介紹了Java實(shí)現(xiàn)拖拽文件上傳dropzone.js的簡(jiǎn)單使用示例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07
Java中IO流使用FileWriter寫(xiě)數(shù)據(jù)基本操作詳解
這篇文章主要介紹了Java中IO流FileWriter寫(xiě)數(shù)據(jù)操作,FileWriter類(lèi)提供了多種寫(xiě)入字符的方法,包括寫(xiě)入單個(gè)字符、寫(xiě)入字符數(shù)組和寫(xiě)入字符串等,它還提供了一些其他的方法,如刷新緩沖區(qū)、關(guān)閉文件等,需要的朋友可以參考下2023-10-10

