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繼承來(lái)的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地址. 也就是說(shuō)如果對(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值不一樣,無(wú)法找到,所以返回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值不一樣,所以無(wú)法找到。
    
    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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容