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

一文搞懂hashCode()和equals()方法的原理

 更新時(shí)間:2020年06月01日 10:13:07   作者:六尺帳篷  
這篇文章主要介紹了詳解hashCode()和equals()的本質(zhì)區(qū)別和聯(lián)系,本文先對兩種方法作了介紹,然后對二者聯(lián)系進(jìn)行分析,具有一定參考價(jià)值,需要的朋友可以了解下

Java中的超類java.lang.Object 有兩個(gè)非常重要的方法:

public boolean equals(Object obj)
public int hashCode()

這兩個(gè)方法最開發(fā)者來說是十分重要的,必須清楚的理解,但實(shí)際上,甚至很多經(jīng)驗(yàn)豐富的Java開發(fā)者有時(shí)候也沒有真正搞清楚這兩個(gè)方法的使用和原理。當(dāng)我們自定義了對象,并且想要將自定義的對象加到Map中時(shí),我們就必須對自定義的對象重寫這兩個(gè)方法,才能正確使用Map。我們接下來將用這篇文章指出在使用hashcode和equals方法時(shí),經(jīng)常范的錯(cuò)誤,并指出如何正確的使用這兩個(gè)方法,以及這兩個(gè)方法工作的原理。

常見的誤區(qū)

看下面這段代碼:

import java.util.HashMap;

public class HashCodeEqual {
  public static void main(String[] args) {
    Apple a1 = new Apple("Blue");
    Apple a2 = new Apple("Green");
    
    HashMap<Apple, Integer> map = new HashMap<>();
    map.put(a1, 10);
    map.put(a2, 20);
    
    System.out.println(map.get(new Apple("Green")));
  }
}

class Apple {
  public String color;
  
  public Apple(String color) {
    this.color = color;
  }
  
  @Override
  public boolean equals(Object obj) {
    if(! (obj instanceof Apple))
      return false;
    if(obj == this)
      return true;
    return this.color.equals(((Apple)obj).color);
  }
}

我們執(zhí)行上面這段代碼

卻發(fā)現(xiàn)與我們預(yù)想的結(jié)果并不一樣,我們想取出map中顏色為Green的apple,最后卻得到一個(gè)null值,這說明map沒有我們需要的顏色為green的apple對象,但實(shí)際上,我們明明向其中添加了一個(gè)顏色為green的apple對象,也重寫了equals方法,為什么最后卻取不出這個(gè)對象呢?

![Upload Paste_Image.png failed. Please try again.]

錯(cuò)誤出現(xiàn)的原因

這個(gè)問題引起的原因是因?yàn)槲覀儧]有重寫“hashCode”方法,這就需要我們深入理解equals方法和hashCode方法的原理:

1 如果兩個(gè)對象是相等的,那么他們必須擁有一樣的hashcode,這是第一個(gè)前提

2 如果兩個(gè)對象有一樣的hashcode,但仍不一定相等,因?yàn)檫€需要第二個(gè)要求,也就是equals方法的判斷。

其實(shí),map判斷對象的方法就是先判斷hashcode是否相等,如果相等再判斷equals方法是否返回true,只有同時(shí)滿足兩個(gè)條件,最后才會被認(rèn)為是相等的。

Map查找元素比線性搜索更快,這是因?yàn)閙ap利用hashkey去定位元素,這個(gè)定位查找的過程分成兩步,內(nèi)部原理中,map將對象存儲在類似數(shù)組的數(shù)組的區(qū)域,所以要經(jīng)過兩個(gè)查找,先找到hashcode相等的,然后在再在其中按線性搜索使用equals方法,通過這兩部來查找一個(gè)對象。

就像上圖這個(gè)結(jié)構(gòu),每個(gè)hashcode對應(yīng)一個(gè)桶,每個(gè)tongli桶里還有多個(gè)對象,確定桶的方法是hashCode,在桶中遍歷線性查找的方法是equals。

在Object中的默認(rèn)的hashCode方法的實(shí)現(xiàn)是為不同的對象返回不同的hashcode,因此如果我們不重寫hashcode方法,那么沒有任何兩個(gè)對象會是相等的,因?yàn)閛bject類中的hashcode實(shí)現(xiàn)是為不同的對象返回不同的hashcode。

所以,我們就搞清楚了上一段代碼出錯(cuò)的原因,由于沒有重寫hashcode方法,所有的對象都是不一樣的,所以我們需要重寫hashcode方法,讓顏色的對象的hashcode是一樣的,比較直接的寫法就是直接用color的length作為hashcode。

public int hashCode(){
return this.color.length();
}

** 切記,一定要同時(shí)重寫hashCode和equals方法 **

以上就是一文搞懂hashCode()和equals()方法的原理的詳細(xì)內(nèi)容,更多關(guān)于hashCode()和equals()方法的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring Boot動態(tài)加載Jar包與動態(tài)配置實(shí)現(xiàn)

    Spring Boot動態(tài)加載Jar包與動態(tài)配置實(shí)現(xiàn)

    隨著項(xiàng)目的不斷演進(jìn)和業(yè)務(wù)需求的增長,很多場景下需要實(shí)現(xiàn)系統(tǒng)的動態(tài)性和靈活性,本文主要介紹了Spring Boot動態(tài)加載Jar包與動態(tài)配置實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • Spring?Security用戶定義?

    Spring?Security用戶定義?

    這篇文章主要介紹了Spring?Security用戶定義,大家都知道?Spring?Security的用戶定義有很多方式,其實(shí)主要有兩種,基于內(nèi)存的和基于數(shù)據(jù)庫的,下面我給大家簡單介紹一下這兩種方式,需要的朋友可以參考下
    2022-02-02
  • Java多線程 自定義線程池詳情

    Java多線程 自定義線程池詳情

    這篇文章主要介紹了Java多線程 自定義線程池,文章主要是學(xué)習(xí)代碼,沒有過多解析,需要的朋友可以參考一下文章的具體內(nèi)容
    2021-10-10
  • Java如何獲取客戶端mac地址

    Java如何獲取客戶端mac地址

    在用戶登錄時(shí),通過獲取IP地址來識別計(jì)算機(jī)的MAC地址,然后將用戶賬號與該MAC地址進(jìn)行綁定,確保每個(gè)賬號只能在一臺特定的計(jì)算機(jī)上登錄,增強(qiáng)系統(tǒng)安全性,這種方法適用于需要嚴(yán)格賬戶安全管理的場景
    2024-09-09
  • Spring Cloud Zuul自定義過濾器的實(shí)現(xiàn)

    Spring Cloud Zuul自定義過濾器的實(shí)現(xiàn)

    這篇文章主要介紹了自定義Spring Cloud Zuul過濾器的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java最全文件操作實(shí)例匯總

    Java最全文件操作實(shí)例匯總

    這篇文章主要介紹了Java最全文件操作,總結(jié)分析了大量實(shí)例,詳細(xì)匯總了Java針對文件的各種常用操作,需要的朋友可以參考下
    2015-11-11
  • SpringBoot訪問HTML過程詳解

    SpringBoot訪問HTML過程詳解

    這篇文章主要詳細(xì)介紹了SpringBoot訪問HTML的全過程,文章中有詳細(xì)的代碼和圖片講解,感興趣的同學(xué)可以參考一下
    2023-04-04
  • java jackson 將對象轉(zhuǎn)json時(shí),忽略子對象的某個(gè)屬性操作

    java jackson 將對象轉(zhuǎn)json時(shí),忽略子對象的某個(gè)屬性操作

    這篇文章主要介紹了java jackson 將對象轉(zhuǎn)json時(shí),忽略子對象的某個(gè)屬性操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • Java實(shí)現(xiàn)規(guī)則幾何圖形的繪制與周長面積計(jì)算詳解

    Java實(shí)現(xiàn)規(guī)則幾何圖形的繪制與周長面積計(jì)算詳解

    隨著計(jì)算機(jī)的發(fā)展,人們對圖形的計(jì)算要求會越來越高。在各行各業(yè)中的計(jì)算人員會對圖形的計(jì)算要有便利的要求,規(guī)則幾何圖形問題求解程序應(yīng)運(yùn)而生!本文將用Java編寫一個(gè)程序,可以實(shí)現(xiàn)規(guī)則幾何圖形的繪制與周長面積計(jì)算,感興趣的可以了解一下
    2022-07-07
  • Spring Boot日志技術(shù)logback原理及配置解析

    Spring Boot日志技術(shù)logback原理及配置解析

    這篇文章主要介紹了Spring Boot日志技術(shù)logback原理及用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07

最新評論