這篇文章主要介紹了Java中hashCode如何求值,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
創(chuàng)新互聯(lián)公司專注于企業(yè)成都全網(wǎng)營(yíng)銷、網(wǎng)站重做改版、靈璧網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、成都商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為靈璧等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
具體如下。
散列表有一項(xiàng)優(yōu)化,可以將對(duì)象的散列碼(hashCode)緩存起來(lái),如果散列碼不匹配,就不會(huì)檢查對(duì)象的等同性而直接認(rèn)為成不同的對(duì)象。如果散列碼(hashCode)相等,才會(huì)檢測(cè)對(duì)象是否相等(equals)。
如果對(duì)象具有相同的散列碼(hashCode),他們會(huì)被映射到同一個(gè)散列桶中。如果散列表中所有對(duì)象的散列碼(hashCode)都一樣,那么該散列表就會(huì)退化為鏈表(linked list),從而大大降低其查詢效率。
一個(gè)好的散列函數(shù)通常傾向于“為不想等的對(duì)象產(chǎn)生不相等的散列碼”。理想情況下,散列函數(shù)應(yīng)該把集合中不想等的實(shí)例均勻地分布到所有可能的散列上,但是想要完全達(dá)到這種理想的情形是非常困難的,下面給出一個(gè)相對(duì)簡(jiǎn)單有效的散列方法:
1.把某個(gè)非零的常數(shù)值,比如說(shuō)17,保存在一個(gè)名為result的int類型的變量中。
2.對(duì)于對(duì)象中的每個(gè)關(guān)鍵域f(指equals方法中涉及的每個(gè)域),完成以下步驟:
為該域計(jì)算int類型的散列碼c
如果該域是boolean類型,則計(jì)算 ( f ? 1 : 0 )
如果該域是byte、char、short或者int類型,則計(jì)算 ( ( int ) f )
如果該域是long類型,則計(jì)算 ( int ) ( f ^ ( f >>> 32 ) )
如果該域是float類型,則計(jì)算Float.floatToIntBits(f)
如果該域是double類型,則計(jì)算Double.doubleToLongBits(f),然后按照上述步驟為得到的long類型值再計(jì)算散列值
如果該域是一個(gè)對(duì)象引用,并且該類的equals方法通過遞歸地調(diào)用equals的方式來(lái)比較它的域,那么同樣為這個(gè)域按上述方法遞歸地調(diào)用hashCode
如果該域是一個(gè)數(shù)組,則要把每一個(gè)元素當(dāng)作單獨(dú)的域來(lái)處理,遞歸地應(yīng)用上述原則,如果數(shù)組中的每一個(gè)元素都很重要,也可以直接使用Arrays.hashCode方法。
按照下面的公式,把上述步驟得到的散列碼c依次合并到result中:result = 31 * result + c;
乘法運(yùn)算是為了得到一個(gè)更好的散列函數(shù)。比如如果String的散列函數(shù)省略了乘法,那么只是字母順序不同的所有字符串都會(huì)有相同的散列碼。這里之所以選擇31,是因?yàn)樗且粋€(gè)奇素?cái)?shù)。如果乘數(shù)是偶數(shù),并且乘法溢出的話,信息就會(huì)丟失,因?yàn)榕c2相乘等價(jià)于位移。使用素?cái)?shù)的好處并不是很明顯,但是習(xí)慣上都使用素?cái)?shù)來(lái)計(jì)算散列結(jié)果。31有個(gè)很好的特性,即用移位和減法來(lái)代替乘法,可以得到更好的性能:31 * i == ( i << 5 ) - i?,F(xiàn)在的VM均可以自動(dòng)實(shí)現(xiàn)這種優(yōu)化。
如果一個(gè)類是不可變的(所有域都是final修飾,并且所有域都為基本類型或者也是不可變類),并且計(jì)算散列碼的開銷也比較大,那么就應(yīng)該考慮把散列碼緩存在對(duì)象內(nèi)部。
public class HashCodeDemo { static class HashCodeClass { private final boolean bResult; private final byte byteValue; private final char charValue; private final short shortValue; private final int intValue; private final long longValue; private final float floatValue; private final double doubleValue; private final String str; private final int[] arrayValue; //volatile表示每次均在內(nèi)存中去存取該變量,以保證該變量是最新的 private volatile int hashCode; public HashCodeClass() { bResult = false; byteValue = 1; charValue = 'a'; shortValue = 1; intValue = 1; longValue = 1l; floatValue = 1.0f; doubleValue = 1.0d; str = getClass().getName(); arrayValue = new int[] {1,2,3,4,5}; } @Override public int hashCode() { if(hashCode == 0) { // 設(shè)置一個(gè)非零的初始值,可以增加零域的沖突性 int result = 17; // 如果省略乘數(shù),那么只是字母順序不同的所有字符串都會(huì)有相同的散列碼 final int HASH_CODE = 31; result = HASH_CODE * result + (bResult ? 1 : 0); result = HASH_CODE * result + byteValue; result = HASH_CODE * result + charValue; result = HASH_CODE * result + shortValue; result = HASH_CODE * result + intValue; result = HASH_CODE * result + (int) (longValue ^ (longValue >>> 32)); result = HASH_CODE * result + Float.floatToIntBits(floatValue); long doubleLongValue = Double.doubleToLongBits(doubleValue); result = HASH_CODE * result + (int) (doubleLongValue ^ (doubleLongValue >>> 32)); result = HASH_CODE * result + (str == null ? 0 : str.hashCode()); System.out.println("str=" + str + ", str.hashCode=" + str.hashCode()); result = HASH_CODE * result + arrayValue.hashCode(); return result; } return hashCode; } } public static void main(String[] args) { HashCodeClass obj = new HashCodeClass(); System.out.println("obj.hashCode=" + obj.hashCode()); System.out.println("obj="+obj.toString()); } }
輸出
str=com.demo.test.HashCodeDemo$HashCodeClass, str.hashCode=-205823051 obj.hashCode=946611167 str=com.demo.test.HashCodeDemo$HashCodeClass, str.hashCode=-205823051 obj=com.demo.test.HashCodeDemo$HashCodeClass@386c23df
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Java中hashCode如何求值”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
新聞名稱:Java中hashCode如何求值
當(dāng)前URL:http://jinyejixie.com/article12/gdjgdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站收錄、標(biāo)簽優(yōu)化、定制網(wǎng)站、虛擬主機(jī)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)