欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java開發(fā)HashMap?key必須實現(xiàn)hashCode?equals方法原理

 更新時間:2023年03月20日 16:25:54   作者:Ciusyan  
這篇文章主要為大家介紹了Java開發(fā)HashMap?key必須實現(xiàn)hashCode?equals方法原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

一、問題引入

平時在開發(fā)中,相信你多多少少都使用過HashMap,而當(dāng)你用自定義對象作為key時,很多人會告訴你:你必須要同時實現(xiàn)自定義對象的hashCode、equals方法,否者可能會出問題,于是你就實現(xiàn)了...

可是為什么呢?比如這里有自定義對象Person,構(gòu)造如下:

public class Person {
    private String name;
    private int age;
    private float height;
}

欲將Person作為HashMap的key,放入哈希表中存儲信息。我們來探討一下,為什么要同時實現(xiàn)hashCode、equals方法吧~

Person p1 = new Person("ciusyan", 21, 1.8f);
Person p2 = new Person("ciusyan", 21, 1.8f);
Map<Person, String> map = new HashMap<>();
map.put(p1, "Ciusyan");
map.put(p2, "Zhiyan");

首先要明確:

  • hashCode方法用于計算出對象的哈希值
  • equlas方法用于比較兩個對象是否相等

二、hashCode、equals方法都未實現(xiàn)

倘若你了解哈希表的基本構(gòu)造,可以畫出一個草圖:

我們并沒有實現(xiàn)hashCode、equals方法,為什么還能放入哈希表中呢?

  • 因為JDK會有默認(rèn)實現(xiàn)

在默認(rèn)的實現(xiàn)中:

  • 利用hashCode方法計算出的哈希值是不同的
  • 利用equals方法比較,p1和p2不是一個對象
  • 所以放入哈希表中的大致結(jié)構(gòu)如上圖所示:
    • 可能會被放入兩個桶(不同哈希值計算出的索引不一樣)
    • 也可能會被放入一個桶(不同哈希值也可能會計算出相同的索引),又因為是不同對象,所以會被串起來

三、只實現(xiàn)hashCode方法

如果我們實現(xiàn)了hashCode方法,會有什么不同呢?

    @Override
	public int hashCode() {
        int hash = Integer.hashCode(age);
        hash = hash * 31 + Float.hashCode(height);
        hash = hash * 31 + (name == null ? 0 : name.hashCode());
        return hash;
    }

如上實現(xiàn),既滿足了盡量用的所有信息,也使計算的值盡量唯一了

如果是現(xiàn)在,我們再來畫一幅草圖:

現(xiàn)在只實現(xiàn)了hashCode方法:

  • 利用hashCode方法計算出的哈希值是相同的
  • equals方法是默認(rèn)實現(xiàn),p1和p2不是一個對象
  • 所以放入哈希表中的大致結(jié)構(gòu)如上圖所示:
    • 只會被放入一個桶(相同的哈希值計算出的索引相同),又因為是不同對象,所以會被串起來

四、只實現(xiàn)equals方法

如果我們實現(xiàn)了equals方法,會有什么不同呢?

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || o.getClass() != getClass()) return false;
        Person p = (Person) o;
        return p.age == age && p.height == height && (Objects.equals(name, p.name));
    }

如上實現(xiàn),如果兩個對象的age、name、height都相等,那么可以認(rèn)為是同一個對象

如果是現(xiàn)在:

現(xiàn)在只實現(xiàn)了equals方法:

  • hashCode方法是默認(rèn)實現(xiàn),計算出的哈希值是不同的
  • 利用equals方法比較,p1和p2是同一個對象
  • 所以放入哈希表中的大致結(jié)構(gòu)如上圖所示:
    • 可能會被放入兩個桶(計算出的索引不一樣)
    • 也可能會被放入一個桶(不同哈希值也可能會計算出相同的索引),又因為是同一對象,所以p2的鍵和值會覆蓋掉p1的

五、hashCode、equals方法都實現(xiàn)

倘若我們用上面的實現(xiàn)方式,將hashCode和equals方法都實現(xiàn)了

來看看最終的結(jié)構(gòu):

現(xiàn)在hashCode、equals方法都實現(xiàn)了:

  • 利用hashCode方法計算出的哈希值是相同的
  • 利用equals方法比較,p1和p2是同一個對象

所以放入哈希表中的大致結(jié)構(gòu)如上圖所示:

  • 只會被放入一個桶中(相同的哈希值計算出的索引相同),又因為是同一對象,所以p2的鍵和值會覆蓋掉p1

六、總結(jié)

如果你想要用自定義對象作為HashMap的key,為什么hashCode、equals方法都要實現(xiàn)?

相信你看完了四種情況,應(yīng)該能說出個balabala...

那我們一起來balabala一下吧~

  • 先利用hashCode方法計算出哈希值:
    • 如果哈希值相同,在哈希表中計算出的索引肯定相同,會被放入一個桶中。這時候用equals方法查看是否是相同的對象。
      • 如果是,用新的鍵和值覆蓋掉舊的;
      • 如果不是就用鏈地址法將對象串起來
    • 如果哈希值不同,在哈希表中計算的索引也可能相同,也就是可能會被放入一個桶,也可能會被放入兩個桶。
      • 如果被放入一個桶中,同上一樣,檢查equlas方法;
      • 如果放入兩個桶中,則不需要查看是否equals

一般的開發(fā)需求會是第四種,想要用p1和p2作為key存儲數(shù)據(jù),會認(rèn)為它們是同一個對象,它們是同一個key,也就只會存儲一份數(shù)據(jù)。所以如果不同時實現(xiàn)hashCode、equals方法,會有圖中的種種問題。

以上就是Java開發(fā)HashMap key必須實現(xiàn)hashCode equals方法原理的詳細(xì)內(nèi)容,更多關(guān)于Java開發(fā)HashMap key的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot整合Lettuce redis過程解析

    SpringBoot整合Lettuce redis過程解析

    這篇文章主要介紹了SpringBoot整合Lettuce redis過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10
  • Spring自動裝配之方法、構(gòu)造器位置的自動注入操作

    Spring自動裝配之方法、構(gòu)造器位置的自動注入操作

    這篇文章主要介紹了Spring自動裝配之方法、構(gòu)造器位置的自動注入操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • centos7安裝java的多種方式總結(jié)

    centos7安裝java的多種方式總結(jié)

    這篇文章主要給大家介紹了關(guān)于centos7安裝java的多種方式,文中通過實例代碼以及圖文介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2023-01-01
  • 帶你了解Java常用類小結(jié)

    帶你了解Java常用類小結(jié)

    今天帶大家學(xué)習(xí)Java常用工具類,文中有非常詳細(xì)的圖文解說及代碼示例,對正在學(xué)習(xí)java的小伙伴們很有幫助,需要的朋友可以參考下,希望能給你帶來幫助
    2021-07-07
  • Spring?Cloud?Alibaba微服務(wù)組件Sentinel實現(xiàn)熔斷限流

    Spring?Cloud?Alibaba微服務(wù)組件Sentinel實現(xiàn)熔斷限流

    這篇文章主要為大家介紹了Spring?Cloud?Alibaba微服務(wù)組件Sentinel實現(xiàn)熔斷限流過程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 詳解springMVC之與json數(shù)據(jù)交互方法

    詳解springMVC之與json數(shù)據(jù)交互方法

    本篇文章主要介紹了詳解springMVC之與json數(shù)據(jù)交互方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Java中WeakHashMap的使用詳解

    Java中WeakHashMap的使用詳解

    這篇文章主要介紹了Java中WeakHashMap的使用詳解,WeakHashMap是一種弱引用的Map,底層數(shù)據(jù)結(jié)構(gòu)為數(shù)組鏈表,與HashMap相比,WeakHashMap的區(qū)別在于它的key存儲為弱引用,在垃圾回收時,如果key沒有被強引用所引用,那么key會被回收掉,需要的朋友可以參考下
    2023-09-09
  • SpringMVC自定義參數(shù)綁定實現(xiàn)詳解

    SpringMVC自定義參數(shù)綁定實現(xiàn)詳解

    這篇文章主要介紹了SpringMVC自定義參數(shù)綁定實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates

    IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-10-10
  • IDEA 創(chuàng)建一個Mybatis Maven項目的方法步驟(圖文)

    IDEA 創(chuàng)建一個Mybatis Maven項目的方法步驟(圖文)

    這篇文章主要介紹了IDEA 創(chuàng)建一個Mybatis Maven項目的方法步驟(圖文),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評論