最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java中hashCode的正確求值方法

 更新時(shí)間:2018年02月01日 10:40:27   作者:司馬懿字仲達(dá)  
這篇文章主要介紹了淺談Java中hashCode的正確求值方法,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下

本文研究的主要是Java中hashCode的正確求值方法的相關(guān)內(nèi)容,具體如下。

散列表有一項(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類(lèi)型的變量中。

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

  • 為該域計(jì)算int類(lèi)型的散列碼c
  • 如果該域是boolean類(lèi)型,則計(jì)算 ( f ? 1 : 0 )
  • 如果該域是byte、char、short或者int類(lèi)型,則計(jì)算 ( ( int ) f )
  • 如果該域是long類(lèi)型,則計(jì)算 ( int ) ( f ^ ( f >>> 32 ) )
  • 如果該域是float類(lèi)型,則計(jì)算Float.floatToIntBits(f)
  • 如果該域是double類(lèi)型,則計(jì)算Double.doubleToLongBits(f),然后按照上述步驟為得到的long類(lèi)型值再計(jì)算散列值
  • 如果該域是一個(gè)對(duì)象引用,并且該類(lèi)的equals方法通過(guò)遞歸地調(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è)類(lèi)是不可變的(所有域都是final修飾,并且所有域都為基本類(lèi)型或者也是不可變類(lèi)),并且計(jì)算散列碼的開(kāi)銷(xiāo)也比較大,那么就應(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

總結(jié)

以上就是本文關(guān)于淺談Java中hashCode的正確求值方法的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專(zhuān)題,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!

相關(guān)文章

  • Java數(shù)組的聲明與創(chuàng)建示例詳解

    Java數(shù)組的聲明與創(chuàng)建示例詳解

    這篇文章主要介紹了Java數(shù)組的聲明與創(chuàng)建示例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 在idea中g(shù)it實(shí)現(xiàn)里查看歷史代碼方式

    在idea中g(shù)it實(shí)現(xiàn)里查看歷史代碼方式

    這篇文章主要介紹了在idea中g(shù)it里查看歷史代碼的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • java9中g(shù)c log參數(shù)遷移

    java9中g(shù)c log參數(shù)遷移

    本篇文章給大家詳細(xì)講述了java9中g(shù)c log參數(shù)遷移的相關(guān)知識(shí)點(diǎn),對(duì)此有需要的朋友可以參考學(xué)習(xí)下。
    2018-03-03
  • java錯(cuò)誤:無(wú)效的源發(fā)行版:18解決辦法圖文詳解

    java錯(cuò)誤:無(wú)效的源發(fā)行版:18解決辦法圖文詳解

    在Java開(kāi)發(fā)中,如果你遇到錯(cuò)誤: 無(wú)效的源發(fā)行版,這通常意味著你正在使用的Java編譯器(通常是javac)被配置為編譯一個(gè)比你的JDK 版本更高,這篇文章主要給大家介紹了關(guān)于java錯(cuò)誤:無(wú)效的源發(fā)行版:18的解決辦法,需要的朋友可以參考下
    2024-08-08
  • Springboot手動(dòng)連接庫(kù)并獲取指定表結(jié)構(gòu)的示例代碼

    Springboot手動(dòng)連接庫(kù)并獲取指定表結(jié)構(gòu)的示例代碼

    這篇文章主要介紹了Springboot手動(dòng)連接庫(kù)并獲取指定表結(jié)構(gòu)的示例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • springboot如何解決非controller類(lèi)引用service的問(wèn)題

    springboot如何解決非controller類(lèi)引用service的問(wèn)題

    這篇文章主要介紹了springboot如何解決非controller類(lèi)引用service的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • IDEA 錯(cuò)誤 No main class specified的問(wèn)題

    IDEA 錯(cuò)誤 No main class specified的問(wèn)題

    這篇文章主要介紹了IDEA 錯(cuò)誤 No main class specified的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • SpringBoot注解@EnableScheduling定時(shí)任務(wù)詳細(xì)解析

    SpringBoot注解@EnableScheduling定時(shí)任務(wù)詳細(xì)解析

    這篇文章主要介紹了SpringBoot注解@EnableScheduling定時(shí)任務(wù)詳細(xì)解析,@EnableScheduling 開(kāi)啟對(duì)定時(shí)任務(wù)的支持,啟動(dòng)類(lèi)里面使用@EnableScheduling 注解開(kāi)啟功能,自動(dòng)掃描,需要的朋友可以參考下
    2024-01-01
  • MyBatis-Plus中最簡(jiǎn)單的查詢操作教程(Lambda)

    MyBatis-Plus中最簡(jiǎn)單的查詢操作教程(Lambda)

    這篇文章主要給大家介紹了關(guān)于MyBatis-Plus中最簡(jiǎn)單的查詢操作的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • Idea 快速生成方法返回值的操作

    Idea 快速生成方法返回值的操作

    這篇文章主要介紹了Idea 快速生成方法返回值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02

最新評(píng)論

道真| 赫章县| 石阡县| 嘉善县| 乡城县| 武邑县| 乌拉特前旗| 高陵县| 聂荣县| 资阳市| 新邵县| 永泰县| 兴安盟| 苏尼特左旗| 和平区| 囊谦县| 阜城县| 乐清市| 太白县| 武清区| 鄂尔多斯市| 普定县| 海阳市| 达日县| 沛县| 灵璧县| 楚雄市| 金溪县| 小金县| 勐海县| 大荔县| 新余市| 姜堰市| 平舆县| 屏山县| 林周县| 石河子市| 镇赉县| 呼和浩特市| 台州市| 东至县|