hashCode()和equals()及==

hashCode()equals()==

Java的約定-《算法4》摘錄

? 每種數(shù)據(jù)類型都需要相應(yīng)的散列函數(shù),于是Java令所有數(shù)據(jù)類型都集成了一個(gè)能夠返回一個(gè)32比特整數(shù)的hashCode()方法. 每一種數(shù)據(jù)類型的hashCode()方法都必須和equals()方法一致.

  • 如果a.equals(b)返回true, 那么a.hashCode()的返回值必然和b.hashCode()返回值相同.

  • 如果兩個(gè)對(duì)象的hashCode()方法的返回值不同, 那么我們就知道這兩個(gè)對(duì)象是不同的.

  • 如果兩個(gè)對(duì)象的hashCode()方法的返回值相同, 這兩個(gè)對(duì)象也有可能不同, 還需要使用equals()方法進(jìn)行判斷.

  • 如果要為自定義的數(shù)據(jù)類型定義散列函數(shù), 需要同時(shí)重寫hashCode()equals()方法. 默認(rèn)的散列函數(shù)會(huì)返回對(duì)象的內(nèi)容地址, 但這只適用很少的情況. Java為很多常用的數(shù)據(jù)類型重寫了hashCode()方法(包括String擎颖、Integer、Double恳啥、File和URL).

    ?

==比較符號(hào):

  • 對(duì)于8中基本的數(shù)據(jù)類型, 比較的是變量所對(duì)應(yīng)內(nèi)存存儲(chǔ)的數(shù)值
  • 對(duì)于指向?qū)ο蟮淖兞?/strong>, 比較的也是變量所對(duì)應(yīng)內(nèi)存存儲(chǔ)的數(shù)值(即指向的對(duì)象占用堆內(nèi)存的首地址), 也就是比較變量是否指向同一個(gè)對(duì)象.

equals():

  • equals方法時(shí)用于比較兩個(gè)獨(dú)立對(duì)象的內(nèi)容是否相同, 需要為類重寫equals方法.
  • 如果一個(gè)類沒有定義自己的equals方法, 它默認(rèn)的equals方法就是從Object繼承來的equals方法, 相當(dāng)于==操作符. 也就是在比較兩個(gè)變量指向的對(duì)象是否為同一個(gè)對(duì)象, 這時(shí)候使用equals和使用==會(huì)得到相同的結(jié)果. 如果編寫的類希望能夠比較該類創(chuàng)建的兩個(gè)實(shí)例對(duì)象的內(nèi)容是否相同, 那么必須覆蓋equals方法.

String類中的equals方法:

public boolean equals(Object anObject) {
        if (this == anObject) {  //如果指向的是同一個(gè)地址仔沿,那內(nèi)容肯定相同
            return true;   
        }
        if (anObject instanceof String) {   // 地址不同時(shí)比較內(nèi)容是否相同
            String anotherString = (String) anObject;   // 判斷是否為String類
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
}

hashCode()

  • 默認(rèn)情況下, Object中的hashCode()返回對(duì)象的32位jvm地址. 也就是說如果對(duì)象不重寫該方法, 則返回相應(yīng)對(duì)象的32位jvm內(nèi)存地址.

  • 當(dāng)equals方法被重寫時(shí), 通常有必要重寫hashCode方法, 以維護(hù) hashCode方法的常規(guī)協(xié)定, 協(xié)定聲明相等對(duì)象必須具有相等的哈希碼.

  • String類中的hashCode:

 public int hashCode() {
     int h = hash;    //Default to 0 ### String類中的私有變量,
     if (h == 0 && value.length > 0) {    //private final char value[]; ### Sting類中保存的字符串內(nèi)容的的數(shù)組
         char val[] = value;

         for (int i = 0; i < value.length; i++) {
             h = 31 * h + val[i];
         }
         hash = h;
     }
     return h;
 }
  • 舉例:

    1. 未重寫hashCode時(shí):
    import java.util.HashMap;
    
    public class Cat {
        private String color;
    
        public Cat(String color) {
            this.color = color;
        }
    
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (!(obj instanceof Cat)) {
                return false;
            }
            if (this == obj) {
                return true;
            }
            return (this.color.equals(((Cat) obj).color));
        }
    
        public static void main(String[] args) {
            Cat cat1 = new Cat("白色");
            Cat cat2 = new Cat("黑色");
            System.out.println(cat1.equals(cat2));  //false逆巍,因?yàn)橹貙懥薳quals方法及塘,且他們的顏色不一樣锐极,所以返回false。
            HashMap<Cat, String> maps = new HashMap<>();
            maps.put(cat1, "白色");
            maps.put(cat2, "黑色");
            System.out.println(maps.get(new Cat("白色")));    //null灵再,因?yàn)闆]有重寫hashcode方法肋层,所以在查找的時(shí)候計(jì)算的hashcode值不一樣翎迁,無法找到,所以返回null汪榔。
        }
    }
    
    
    對(duì)于Java中所有類的超級(jí)父類java.lang.Object而言,其hashCode()的默認(rèn)實(shí)現(xiàn)是:對(duì)于不同的對(duì)象就返回不同的整型值。上述示例代碼中全陨,Cat類沒有重寫Object的hashCode()方法爆班。所以辱姨,這條代碼System.out.println(maps.get(new Cat("白色")));創(chuàng)建的Cat類和cat1的hasncode值不一樣,所以無法找到雨涛。
    
    1. 重寫hashCode
    import java.util.HashMap;
    
    public class Cat {
        private String color;
    
        public Cat(String color) {
            this.color = color;
        }
    
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (!(obj instanceof Cat)) {
                return false;
            }
            if (this == obj) {
                return true;
            }
            return (this.color.equals(((Cat) obj).color));
        }
    
        @Override
        public int hashCode() {
            return this.color.hashCode();
        }
    
        public static void main(String[] args) {
            Cat cat1 = new Cat("白色");
            Cat cat2 = new Cat("黑色");
            System.out.println(cat1.equals(cat2)); // false
            HashMap<Cat, String> maps = new HashMap<>();
            maps.put(cat1, "白色");
            maps.put(cat2, "黑色");
            System.out.println(maps.get(new Cat("白色"))); // 白色
        }
    }
    

    摘自: 簡(jiǎn)書.

    參考: 1. ==和equals的區(qū)別

    ? 2. hashCode和equals相關(guān)問題闡述

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市替久,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蚯根,老刑警劉巖后众,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件颅拦,死亡現(xiàn)場(chǎng)離奇詭異蒂誉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)距帅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門右锨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碌秸,你說我怎么就攤上這事绍移。” “怎么了讥电?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵蹂窖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我恩敌,道長(zhǎng)瞬测,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任潮剪,我火速辦了婚禮,結(jié)果婚禮上分唾,老公的妹妹穿的比我還像新娘抗碰。我一直安慰自己,他們只是感情好绽乔,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布弧蝇。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪看疗。 梳的紋絲不亂的頭發(fā)上沙峻,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音两芳,去河邊找鬼摔寨。 笑死,一個(gè)胖子當(dāng)著我的面吹牛怖辆,可吹牛的內(nèi)容都是我干的是复。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼竖螃,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼淑廊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起特咆,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤季惩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后腻格,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體画拾,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年荒叶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碾阁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡脂凶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蚕钦,到底是詐尸還是另有隱情,我是刑警寧澤嘶居,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布促煮,位于F島的核電站,受9級(jí)特大地震影響菠齿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绳匀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一炸客、第九天 我趴在偏房一處隱蔽的房頂上張望戈钢。 院中可真熱鬧,春花似錦殉了、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痕囱。三九已至,卻和暖如春鞍恢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背帮掉。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留稽莉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓污秆,卻偏偏與公主長(zhǎng)得像昧甘,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子充边,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 前言 Java的基類Object提供了一些方法,其中equals()方法用于判斷兩個(gè)對(duì)象是否相等贬媒,hashCode...
    余平的余_余平的平閱讀 2,669評(píng)論 0 5
  • 1. “==”比較的是什么 ==是一個(gè)運(yùn)算符 對(duì)于8種基本的數(shù)據(jù)類型肘习,比較的是變量所對(duì)應(yīng)內(nèi)存存儲(chǔ)的數(shù)值 對(duì)于指向?qū)?..
    暖熊熊閱讀 769評(píng)論 0 1
  • (一)Java部分 1、列舉出JAVA中6個(gè)比較常用的包【天威誠(chéng)信面試題】 【參考答案】 java.lang;ja...
    獨(dú)云閱讀 7,118評(píng)論 0 62
  • 左權(quán)老弟年輕時(shí)蚓庭,略略有點(diǎn)膽怯,不太敢去追心儀的女孩子器赞。打麻將也不太利索。但他骨子里有一股不服輸?shù)膭蓬^港柜,看大事,比一...
    喬橋閱讀 429評(píng)論 0 2
  • 樓頭月夏醉,梢上鵲,黃燈人影流螢掠畔柔。愁云聚,絲雨薄臣樱。羅裙易濕,淚痕難絕雇毫。卻、卻棚放、卻。 身相隔飘蚯,心難別,欲訴衷腸語凝咽孝冒。...
    九月思閱讀 309評(píng)論 0 0