Java中hashCode如何求值-創新互聯

這篇文章主要介紹了Java中hashCode如何求值,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

成都創新互聯公司從2013年成立,是專業互聯網技術服務公司,擁有項目網站設計制作、成都網站制作網站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元臨川做網站,已為上家服務,為臨川各地企業和個人服務,聯系電話:028-86922220

具體如下。

散列表有一項優化,可以將對象的散列碼(hashCode)緩存起來,如果散列碼不匹配,就不會檢查對象的等同性而直接認為成不同的對象。如果散列碼(hashCode)相等,才會檢測對象是否相等(equals)。

如果對象具有相同的散列碼(hashCode),他們會被映射到同一個散列桶中。如果散列表中所有對象的散列碼(hashCode)都一樣,那么該散列表就會退化為鏈表(linked list),從而大大降低其查詢效率。

一個好的散列函數通常傾向于“為不想等的對象產生不相等的散列碼”。理想情況下,散列函數應該把集合中不想等的實例均勻地分布到所有可能的散列上,但是想要完全達到這種理想的情形是非常困難的,下面給出一個相對簡單有效的散列方法:

1.把某個非零的常數值,比如說17,保存在一個名為result的int類型的變量中。

2.對于對象中的每個關鍵域f(指equals方法中涉及的每個域),完成以下步驟:

  • 為該域計算int類型的散列碼c

  • 如果該域是boolean類型,則計算 ( f ? 1 : 0 )

  • 如果該域是byte、char、short或者int類型,則計算 ( ( int ) f )

  • 如果該域是long類型,則計算 ( int ) ( f ^ ( f >>> 32 ) )

  • 如果該域是float類型,則計算Float.floatToIntBits(f)

  • 如果該域是double類型,則計算Double.doubleToLongBits(f),然后按照上述步驟為得到的long類型值再計算散列值

  • 如果該域是一個對象引用,并且該類的equals方法通過遞歸地調用equals的方式來比較它的域,那么同樣為這個域按上述方法遞歸地調用hashCode

  • 如果該域是一個數組,則要把每一個元素當作單獨的域來處理,遞歸地應用上述原則,如果數組中的每一個元素都很重要,也可以直接使用Arrays.hashCode方法。

  • 按照下面的公式,把上述步驟得到的散列碼c依次合并到result中:result = 31 * result + c;   乘法運算是為了得到一個更好的散列函數。比如如果String的散列函數省略了乘法,那么只是字母順序不同的所有字符串都會有相同的散列碼。這里之所以選擇31,是因為它是一個奇素數。如果乘數是偶數,并且乘法溢出的話,信息就會丟失,因為與2相乘等價于位移。使用素數的好處并不是很明顯,但是習慣上都使用素數來計算散列結果。31有個很好的特性,即用移位和減法來代替乘法,可以得到更好的性能:31 * i == ( i << 5 ) - i。現在的VM均可以自動實現這種優化。

如果一個類是不可變的(所有域都是final修飾,并且所有域都為基本類型或者也是不可變類),并且計算散列碼的開銷也比較大,那么就應該考慮把散列碼緩存在對象內部。

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表示每次均在內存中去存取該變量,以保證該變量是最新的
    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) {
        // 設置一個非零的初始值,可以增加零域的沖突性
        int result = 17;
        // 如果省略乘數,那么只是字母順序不同的所有字符串都會有相同的散列碼
        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

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Java中hashCode如何求值”這篇文章對大家有幫助,同時也希望大家多多支持創新互聯,關注創新互聯行業資訊頻道,更多相關知識等著你來學習!

網頁名稱:Java中hashCode如何求值-創新互聯
鏈接URL:http://m.kartarina.com/article12/cdscdc.html

成都網站建設公司_創新互聯,為您提供網站營銷靜態網站網站策劃全網營銷推廣移動網站建設網站設計

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網站建設公司
主站蜘蛛池模板: 无码乱肉视频免费大全合集| 久久久久亚洲av无码尤物| 国产成人无码免费视频97 | AV无码精品一区二区三区宅噜噜 | 精品久久久久久无码专区| 日日摸日日碰人妻无码| 日韩精品无码视频一区二区蜜桃| 亚洲中文无码线在线观看| 亚洲精品人成无码中文毛片 | 中日精品无码一本二本三本| 无码粉嫩小泬无套在线观看| 亚洲国产精品成人精品无码区在线 | 国产精品无码久久av不卡| 无码国产伦一区二区三区视频| 国产成人精品无码一区二区三区 | 中文字字幕在线中文无码| 无码亚洲成a人在线观看| 亚洲综合一区无码精品| 亚洲Av无码一区二区二三区| 国精品无码一区二区三区左线| 国产aⅴ无码专区亚洲av| 内射中出无码护士在线| 日韩av无码国产精品| 精品一区二区三区无码视频| 国产精品无码一区二区在线观一| 国产精品热久久无码av| 亚洲无码高清在线观看| 无码一区二区三区亚洲人妻| 亚洲aⅴ无码专区在线观看 | 日韩aⅴ人妻无码一区二区| 永久免费av无码不卡在线观看 | 无遮掩无码h成人av动漫| 无码人妻丰满熟妇区96| 亚洲精品无码高潮喷水A片软| 秋霞无码一区二区| 少妇爆乳无码专区| 性色av无码不卡中文字幕| 亚洲日韩VA无码中文字幕| 色欲香天天综合网无码| 亚洲av无码天堂一区二区三区| 亚洲人成无码网WWW|