摘要:如果調用父類的方法,且返回值是返回的值卻不同,因此在覆寫方法的同時覆寫方法。這樣才能最大限度地保證,在程序運行過程中盡可能少的出現莫名其妙的錯誤。
在比較兩個實例是否相等的時候,通常會覆寫equal()方法,然后對類對象的每一成員進行逐一比較,但是JavaSE6規范如下:
應用程序的執行期間,只要對象的equals方法的比較操作所用到的信息沒有被修改,那么對這同一個對象調用多次,hashCode方法都必須始終如一地返回同一個整數。在同一個應用程序的多次執行過程中,每次執行所返回的整數可以不一致。
如果兩個對象根據equals()方法比較是相等的,那么調用這兩個對象中任意一個對象的hashCode方法都必須產生同樣的整數結果。
如果調用父類的equal()方法,且x.equal(y)返回值是true,返回的hashCode值卻不同,因此在覆寫equal()方法的同時覆寫hashCode()方法。這樣才能最大限度地保證,在程序運行過程中盡可能少的出現莫名其妙的錯誤。
再此之前我們先看一下String類中的hashCode()方法:
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = value; for (int i = 0; i < value.length; i++) { h = 31 * h + val[i]; } hash = h; } return h; }
大家可能會覺得莫名其妙,hashCode()方法返回的是一個int類型的值,難道這就是所謂的hashCode?不要急,我們來看一段話,
一個好的散列函數通常傾向于“為不相等的對象產生不相等的散列碼”
對于對象中的每個關鍵域f(指equal方法中涉及的每個域),完成以下步驟:如果該域是boolean類型,則計算(f?1:0);
如果該域是byte、char、short或者int計算(int)f;
如果該域是long型,計算(int)(f^(f>>>32));
如果該域是float類型,計算Float.floatTOIntBits(f);
如果該域是double類型,計算Double.doubleToLongBits(f),然后再根據long型計算得到散列值;
如果該域是一個引用對象,并且該類的equal方法通過遞歸調用equal的方法來比較這個域,則同樣為這個域遞歸調用hashCode,如果這個域為空,則返回0;
-如果該域是一個數組,則要把每一個元素當作多帶帶的域來處理按照下面的公式,把上面計算得到的散列碼c合并到result中
result=31*result+c;
--------------摘自Effective Java
這是EffectiveJava中給出的計算散列碼的方法,當然,方法并不是唯一,只要我們保證相同的對象會產生相同的散列碼,不同的獲得的散列碼不同就可以了。
現在我們回過頭來看看String類中的hashCode方法
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) {//判斷hash值不為0,字符串不為空(即長度大于0) char val[] = value;//將字符串的值轉化為char型數組 for (int i = 0; i < value.length; i++) { h = 31 * h + val[i];//遍歷char數組中的每一個元素通過計算得到hash值 } hash = h; } return h; }
看到這里相信大家已經明了,hash散列碼的意義所在,
這里我們給出一段三個域都是int的hash值計算實例
@Override public int hashCode() { int result = hashCode; //生成對象的唯一散列碼 if (result == 0) { result = result * 31 + areaCode; result = result * 31 + prefix; result = result * 31 + lineNumber; hashCode=result; } return hashCode; }
最后,如果大家想深入學習java的話,建議大家看一看effective java,相信會收獲頗豐的。
我的文章列表
Email:sxh13208803520@gmail.com
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66959.html
摘要:常用方法取的對象信息類的方法返回一個字符串,該字符串由類名對象是該類的一個實例標記符和此對象哈希碼的無符號十六進制表示組成。方法返回的運行時類類型。至于同一個應用程序在不同執行期所得的調用結果,無需一致。 概念 object 類位于 java.lang 包中,是所有 Java 類的祖先,Java 中的每個類都由它擴展而來. 在定義一個類時,如果沒有明確的繼承一個父類的話,那么它繼承的就...
數組 數組是我們比較熟悉的一種數據結構:固定大小,索引(下標)對應的槽位用以存儲數據: showImg(https://segmentfault.com/img/bV7rJ8?w=480&h=119); 我們要在數組中查找一個值,比如紅框圈中的 元素5 ,可以通過遍歷或者排序后二分的方式達到目的。沒有更快捷的查找方式了嗎?顯然是有的,比如Map。我們對存 / 取動一動腦筋,還是上圖的那些元素,假如...
摘要:關于的源碼分析,本文并不打算展開講了。大家可以參考我之前的一篇文章源碼詳細分析。在刪除節點時,父類的刪除邏輯并不會修復所維護的雙向鏈表,這不是它的職責。在節分析鏈表建立過程時,我故意忽略了部分源碼分析。 1. 概述 LinkedHashMap 繼承自 HashMap,在 HashMap 基礎上,通過維護一條雙向鏈表,解決了 HashMap 不能隨時保持遍歷順序和插入順序一致的問題。除此...
摘要:概述引入了新的語言特性默認方法。覆寫默認方法,這跟類與類之間的覆寫規則相類似。靜態默認方法的另一個特性是接口可以聲明并且可以提供實現靜態方法本文首發于凌風博客新特性之默認方法作者凌風 1. 概述 Java 8 引入了新的語言特性——默認方法(Default Methods)。 默認方法允許您添加新的功能到現有庫的接口中,并能確保與采用舊版本接口編寫的代碼的二進制兼容性。 1.1 為什么...
摘要:在二叉查找樹強制一般要求以外,對于任何有效的紅黑樹增加了如下的額外要求節點是紅色或黑色。紅黑樹有哪些應用場景內核和系統調用實現中使用的完全公平調度程序使用紅黑樹。 前言 這篇文章是記錄自己分析 Java 8 的 HashMap 源碼時遇到的疑問和總結,在分析的過程中筆者把遇到的問題都記錄下來,然后逐一擊破,如果有錯誤的地方,希望讀者可以指正,筆者感激不盡。 疑問與解答 什么是 initia...
閱讀 738·2021-11-11 16:54
閱讀 3053·2021-09-26 09:55
閱讀 2004·2021-09-07 10:20
閱讀 1198·2019-08-30 10:58
閱讀 1040·2019-08-28 18:04
閱讀 698·2019-08-26 13:57
閱讀 3584·2019-08-26 13:45
閱讀 1150·2019-08-26 11:42