国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 搞懂JAVAObject中的hashCode()

搞懂JAVAObject中的hashCode()

2021-11-16 13:30馬走日mazouri Java教程

今天小編就為大家分享一篇關于關于Object中equals方法和hashCode方法判斷的分析,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

Object中的hashCode()

hashCode方法用來返回對象的哈希值,提供該方法是為了支持哈希表,例如HashMap,HashTable等,在Object類中的代碼如下:

?
1
public native int hashCode();

這是一個native聲明的本地方法,返回一個int型的整數。由于在Object中,因此每個對象都有一個默認的哈希值。

在openjdk8根路徑/hotspot/src/share/vm/runtime路徑下的synchronizer.cpp文件中,有生成哈希值的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
static inline intptr_t get_next_hash(Thread * Self, oop obj) {
  intptr_t value = 0 ;
  if (hashCode == 0) {
     // 返回隨機數
     value = os::random() ;
  } else
  if (hashCode == 1) {
     //用對象的內存地址根據某種算法進行計算
     intptr_t addrBits = cast_from_oop<intptr_t>(obj) >> 3 ;
     value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
  } else
  if (hashCode == 2) {
     // 始終返回1,用于測試
     value = 1 ;           
  } else
  if (hashCode == 3) {
     //從0開始計算哈希值
     value = ++GVars.hcSequence ;
  } else
  if (hashCode == 4) {
     //輸出對象的內存地址
     value = cast_from_oop<intptr_t>(obj) ;
  } else {
     // 默認的hashCode生成算法,利用xor-shift算法產生偽隨機數
     unsigned t = Self->_hashStateX ;
     t ^= (t << 11) ;
     Self->_hashStateX = Self->_hashStateY ;
     Self->_hashStateY = Self->_hashStateZ ;
     Self->_hashStateZ = Self->_hashStateW ;
     unsigned v = Self->_hashStateW ;
     v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
     Self->_hashStateW = v ;
     value = v ;
  }
 
  value &= markOopDesc::hash_mask;
  if (value == 0) value = 0xBAD ;
  assert (value != markOopDesc::no_hash, "invariant") ;
  TEVENT (hashCode: GENERATE) ;
  return value;
}

源碼中的hashCode其實是JVM啟動的一個參數,每一個分支對應一個生成策略,通過-XX:hashCode可以切換hashCode的生成策略。

下面驗證第2種生成策略,用軟件idea輸入參數-XX:hashCode=2,可以看到輸出結果正是1,從而進一步驗證了上面的源碼。

搞懂JAVAObject中的hashCode()

搞懂JAVAObject中的hashCode()

hashCode()和equals()

hashCode()和equals()用來標識對象,兩個方法協同工作用來判斷兩個對象是否相等。對象通過調用 Object.hashCode()生成哈希值,由于不可避免地會存在哈希值沖突的情況 因此hashCode 相同時 還需要再調用 equals 進行一次值的比較,但是若hashCode不同,將直接判定兩個對象不同,跳過 equals ,這加快了沖突處理效率。 Object 類定義中對 hashCode和 equals 要求如下:

  • 如果兩個對象的equals的結果是相等的,則兩個對象的 hashCode 的返回結果也必須是相同的。
  • 任何時候重寫equals,都必須同時重寫hashCode。

下面看一個小例子:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.util.HashMap;
import java.util.Objects;
 
/**
 * @author mazouri
 * @create 2021-08-10 23:59
 */
public class Person {
    //用戶Id,唯一確定用戶
    private String id;
    private String name;
 
    public Person(String id, String name) {
        this.id = id;
        this.name = name;
    }
 
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return Objects.equals(id, person.id) && Objects.equals(name, person.name);
    }
 
    public static void main(String[] args) {
        HashMap<Person, Integer> map = new HashMap<>();
        //key:Person類型  value:Integer類型
        map.put(new Person("1","張三"),100);
        System.out.println(map.get(new Person("1", "張三")));
    }
}

我們將Person類的實例作為key,value為這個對象的考試成績。我們期望通過map.get(new Person("1", "張三"))獲取該對象的考試成績,但上面代碼的輸出結果為null。原因就在于Person類中沒有覆蓋hashCode方法,從而導致兩個相等的實例具有不同的哈希值。HashMap中get()的核心代碼如下

?
1
2
if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))
     return first;

if條件表達式中的e.hash == hash是先決條件,只有相等才會執行&&后面的代碼。equals不相等時并不強制要求哈希值相等,但是一個優秀的哈希算法應盡可能讓元素均勻分布,降低沖突發生的概率,即在equals不相等時盡量讓哈希值也不相等,這樣&&或||短路操作一旦生效,會極大提高程序的效率。像上面的例子,因為沒有重寫hashCode方法,兩個對象有兩個哈希值,獲取對象時可能在別的哈希桶中查找,即使湊巧在一個哈希桶,因為哈希值不一樣,也找不到原來那一個對象。
你可以根據你自己的需求設計重寫hashCode方法,或者調用JDK提供好的,比如

?
1
2
3
4
@Override
  public int hashCode() {
      return Objects.hash(id, name);
  }

這樣就能解決問題,但是這個運行速度慢一些,因為它們會引發數組的創建,以便傳入數目可變的參數, 如果參數中有基本類型,還需要裝箱和拆箱 ,建議只將這類散列函數用于不太注重性能的情況。

重寫的hashCode()方法

Java為許多常用的數據類型重寫了hashCode()方法,比如String,Integer,Double等。比如在Integer類中哈希值就是其int類型的數據。

?
1
2
3
public static int hashCode(int value) {
      return value;
  }

總結

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://blog.csdn.net/weixin_46215617/article/details/119611129

延伸 · 閱讀

精彩推薦
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 中文字幕一区二区三区精彩视频 | 亚洲午夜成激人情在线影院 | 二区在线观看 | 免费一区二区三区四区 | 欧美激情一区二区三级高清视频 | 高清视频一区 | 好看的国产精彩视频 | 91久久九色| 人人干日日干 | 国产成人jvid在线播放 | 国产欧美日韩二区 | sese综合| 国产综合区 | 国产区在线 | 日韩av在线免费 | 国产精品视频一区二区三区不卡 | 国产黄色一级录像 | 在线精品一区二区 | 性视频一区二区 | 欧美国产日韩一区二区三区 | 久久在线看 | 精品久久久久久久久久久久久久 | 亚洲伦理 | 欧洲精品久久久 | 韩国精品一区 | 国产一区在线免费观看 | 国产乱码精品一区二区三区av | 国产视频一区二区三区在线观看 | 中文字幕的 | 国产精品1区2区 | 久草在线 | 午夜一区二区三区 | 精品无码久久久久久久动漫 | 久久资源av| 国产精品欧美一区二区三区不卡 | 天天插天天操 | 国产精品视屏 | 欧美日韩亚洲国产 | 国产精品美女久久久久久久久久久 | 亚洲精品一区在线观看 | 久久久精品日韩 |