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

細(xì)品Java8中hashCode方法的使用

 更新時間:2020年12月02日 11:45:59   作者:Jeff、yuan  
這篇文章主要介紹了細(xì)品Java8中hashCode方法的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

簡介

散列函數(shù)(英語:Hash function)又稱散列算法、哈希函數(shù),是一種從任何一種數(shù)據(jù)中創(chuàng)建小的數(shù)字“指紋”的方法。散列函數(shù)把消息或數(shù)據(jù)壓縮成摘要,使得數(shù)據(jù)量變小,將數(shù)據(jù)的格式固定下來。

Java語言對hashCode的應(yīng)用

主要用途

  1. hashcode是Object中的函數(shù),所有類都擁有的一個函數(shù),主要返回每個對象的hash值,主要用于哈希表中,如HashMap、HashTable、HashSet。
  2. 在這里需要注意的是,他就是為了在一些對象數(shù)組里面存儲的時候可以節(jié)省空間。(我在這里一直有個誤會,就是hashCode 也會應(yīng)用于對象的比較,主要比較的是對象的是否有被改變過,其實我們在進行比較的時候可以不進進行重寫hashCode,單個的equals就可以保證這個對象是否相等。
  3. 但是很多面試官都會問到,你重寫了equals 不重寫hashcode 可以嗎?不一定,當(dāng)你重寫的equals是那種兩個對象所有值都相等的情況下的時候,我們就不需要重寫。因為這樣他就符合我們的正常邏輯,就是equals相等hashcode值一定相等。但是如果你的equals定義是只要這個對象中某個值相等就代表,這個對象相等,那么傳統(tǒng)觀念就被打破了。所以你就得按照你的equals來重寫你的hashcode。保持一致。

Java 中hashcode存儲的位置

存儲在對象頭markWord,如下圖(深入理解Java虛擬機)

我們知道了他是存儲的位置,那他是什么時候存儲進去的呢? 在Java中所有的對象都是有hashcode嗎?

Java中HashCode的實現(xiàn):

在Java中Object.class中有hashCode方法,方法是native 方法,實現(xiàn)就是在JVM中實現(xiàn)的,也就是說他是使用C語言實現(xiàn)的。

實現(xiàn)方式:OpenJDK8 默認(rèn)hashCode的計算方法是通過和當(dāng)前線程有關(guān)的一個隨機數(shù)+三個確定值,運用Marsaglia's xorshift scheme隨機數(shù)算法得到的一個隨機數(shù)。和對象內(nèi)存地址無關(guān)。三個確定確定值分別是:

// thread-specific hashCode stream generator state - Marsaglia shift-xor form
  //隨機數(shù)
 _hashStateX = os::random() ;
  //確定值1
 _hashStateY = 842502087 ;
   //確定值2
 _hashStateZ = 0x8767 ;  // (int)(3579807591LL & 0xffff) 
   //確定值3
 _hashStateW = 273326509 ;

可以通過在JVM啟動參數(shù)中添加-XX:hashCode=4,改變默認(rèn)的hashCode計算方式。

為什么要重寫hashCode

如上文提到,我們不按傳統(tǒng)規(guī)則重寫了equals方法,所以為了不違反規(guī)則也就得重寫hashCode。

源碼中hashcode的重寫,如hashMap中

如果m1.entrySet( ).equals(m2.entrySet()),則兩個映射m1和 m2表示相同的映射 。這樣可確保 equals方法可在Map接口的不同實現(xiàn)中正常工作。

  static <K, V> boolean equals(Map<K, V> source, Object object) {
    if (source == object) {
      return true;
    } else if (source != null && object instanceof Map) {
      final Map<K, V> map = (Map<K, V>) object;
      if (source.size() != map.size()) {
        return false;
      } else {
        try {
          return source.forAll(map::contains);
        } catch (ClassCastException e) {
          return false;
        }
      }
    } else {
      return false;
    }
  }

映射的哈希碼定義為映射的entrySet()視圖中每個條目的哈希碼之和 。這確保了m1.equals(m2) 隱含了對任何兩個映射 m1和m2的m1.hashCode()== m2.hashCode(),這是的總合同要求的 。Object.hashCode()

  @Override
  public int hashCode() {
    return Collections.hashUnordered(this);
  }
  
    // hashes the elements regardless of their order
  static int hashUnordered(Iterable<?> iterable) {
    return hash(iterable, (acc, hash) -> acc + hash);
  }

注意點 hashMap重寫hashCode 和 計算hash桶位置的是不同的,這兩個可不敢弄混了,我是弄混了。 下來我們再看看hash桶下表的計算。jdk 1.8中的。

/ ** *計算key.hashCode()并將(XOR)散列的較高位*擴展到較低位。
  * 因為該表使用2的冪次掩碼,所以*僅在當(dāng)前掩碼上方的位中發(fā)生變化的*哈希集將**總是發(fā)生沖突。 (眾所周知的示例是Float鍵集*在小表中保存連續(xù)的整數(shù)。)
  *因此,我們*應(yīng)用了一種變換,向下擴展了較高位的影響。在速度,效用和比特擴展*質(zhì)量之間需要權(quán)衡。由于許多常見的哈希集*已經(jīng)合理地分布了(因此不能從*擴展*中受益),并且由于我們使用樹來處理bin中的大量*沖突集,因此我們僅以*最便宜&的方式對一些移位后的位進行XOR運算,減少系統(tǒng)損失,以及*合并最高位的影響,否則由于表的限制,這些位將永遠(yuǎn)不會在索引計算中使用
  * /
  static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  }

總結(jié)

  • hashCode的簡介
  • Java 中 Object.hashCode()的實現(xiàn)
  • 為什么要重寫hashCode()?不打破傳統(tǒng)規(guī)則
  • HashMap中hashCode方法的重寫。
  • HashMap中hash桶的hash計算。

參考

https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#hashCode()
https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#equals(java.lang.Object)
https://juejin.cn/post/6844903487432556551

到此這篇關(guān)于細(xì)品Java8中hashCode方法的使用的文章就介紹到這了,更多相關(guān)Java8 hashCode內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Scala的隱式轉(zhuǎn)換詳解

    Java Scala的隱式轉(zhuǎn)換詳解

    隱式轉(zhuǎn)換是在Scala編譯器進行類型匹配時,如果找不到合適的類型,那么隱式轉(zhuǎn)換會讓編譯器在作用范圍內(nèi)自動推導(dǎo)出來合適的類型。本文通過代碼示例介紹了Scala的隱式轉(zhuǎn)換,感興趣的小伙伴可以參考閱讀
    2023-04-04
  • Protobuf的簡要介紹及使用詳解

    Protobuf的簡要介紹及使用詳解

    這篇文章主要介紹了Protobuf的簡要介紹及使用,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Java關(guān)鍵字instanceof用法及實現(xiàn)策略

    Java關(guān)鍵字instanceof用法及實現(xiàn)策略

    instanceof 運算符是用來在運行時判斷對象是否是指定類及其父類的一個實例。這篇文章主要介紹了Java關(guān)鍵字instanceof用法解析,需要的朋友可以參考下
    2020-08-08
  • Java中多態(tài)性的實現(xiàn)方式

    Java中多態(tài)性的實現(xiàn)方式

    這篇文章主要介紹了Java中多態(tài)性的實現(xiàn)方式,什么是多態(tài)?通過簡單的一道題目幫大家理解java多態(tài)性,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • IDEA類存在但找不到的解決辦法

    IDEA類存在但找不到的解決辦法

    本文主要介紹了IDEA類存在但找不到的解決辦法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • Java線程中的ThreadLocal類解讀

    Java線程中的ThreadLocal類解讀

    這篇文章主要介紹了Java線程中的ThreadLocal類解讀,ThreadLocal是一個泛型類,作用是實現(xiàn)線程隔離,ThreadLocal類型的變量,在每個線程中都會對應(yīng)一個具體對象,對象類型需要在聲明ThreadLocal變量時指定,需要的朋友可以參考下
    2023-11-11
  • springboot+camunda實現(xiàn)工作流的流程分析

    springboot+camunda實現(xiàn)工作流的流程分析

    Camunda是基于Java語言,支持BPMN標(biāo)準(zhǔn)的工作流和流程自動化框架,并且還支持CMMN規(guī)范,DMN規(guī)范,本文給大家介紹springboot+camunda實現(xiàn)工作流的流程分析,感興趣的朋友一起看看吧
    2021-12-12
  • Seata?AT模式啟動過程圖文示例詳解

    Seata?AT模式啟動過程圖文示例詳解

    這篇文章主要為大家介紹了Seata?AT模式啟動過程圖文示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Java線程池獲取池中所有線程列表的方法總結(jié)

    Java線程池獲取池中所有線程列表的方法總結(jié)

    在Java中,獲取線程池中所有線程列表并不是一個直接支持的功能,因為線程池的設(shè)計通常是為了隱藏和管理底層的線程細(xì)節(jié),從而提供更高層次的抽象和并發(fā)控制能力,本文給大家介紹了Java線程池獲取池中所有線程列表的方法,需要的朋友可以參考下
    2024-10-10
  • Jackson2的JsonSchema實現(xiàn)java實體類生成json方式

    Jackson2的JsonSchema實現(xiàn)java實體類生成json方式

    這篇文章主要介紹了Jackson2的JsonSchema實現(xiàn)java實體類生成json,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評論

南部县| 溧阳市| 昌吉市| 方正县| 安仁县| 保亭| 肇源县| 红原县| 政和县| 简阳市| 铜川市| 沿河| 庆元县| 安化县| 绥江县| 石景山区| 睢宁县| 济南市| 老河口市| 香港 | 泉州市| 乐安县| 黄大仙区| 繁昌县| 霍山县| 黄山市| 大悟县| 喀什市| 兴和县| 宁蒗| 历史| 临夏县| 五莲县| 德昌县| 衡东县| 合川市| 柳河县| 富川| 渝中区| 古交市| 文山县|