為什么重寫equals()方法,必須重寫hashCode()方法嘴高?

為了弄清為什么重寫equals()方法時炉擅,必須重寫hashCode()方法辉懒,我們首先需要明確Object實現(xiàn)hashCode()返回值是什么?

    /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * <p>
     * The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined by
     * class {@code Object} does return distinct integers for distinct
     * objects. (This is typically implemented by converting the internal
     * address of the object into an integer, but this implementation
     * technique is not required by the
     * Java&trade; programming language.)
     *
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();

哈希碼的通用約定如下:

  • 在java程序執(zhí)行過程中谍失,在一個對象沒有被改變的前提下眶俩,無論這個對象被調(diào)用多少次,hashCode()方法都會返回相同的整數(shù)值快鱼。對象的哈希碼沒有必要在不同的程序中保持相同的值颠印。
  • 如果兩個對象使用equals()方法進行比較是等價的,那么這兩個對象的hashCode()方法必須返回相同的值抹竹。
  • 如果兩個對象使用equals()方法進行比較是不等價的线罕,那么這兩個對象的hashCode()方法返回值不必相同。但是窃判,不等價的對象的hashCode()值不同的話可以提高哈希表的性能钞楼。

hashCode()方法是一個native方法,它返回的是由對象存儲地址轉(zhuǎn)化得到的值袄琳。

若重寫equals()方法而不重寫hashCode()方法询件,當(dāng)兩個對象使用equals()方法進行比較是等價的時,兩個對象的hashCode()方法返回值是不想等的(兩個對象的存儲地址是不相同的)唆樊,違背了哈希碼通用約定第二條宛琅。

下面的代碼中,新建了兩個等價的對象person1和person2逗旁,并將person1作為key存入HashMap中嘿辟。我們希望將這兩個對象當(dāng)成一個key,在HashMap中取person2的時候可以返回鍵person1的value片效。由于只重寫了equals()方法红伦,而未重寫hashCode()方法,實際返回值為null淀衣。

public class Person {
    private int id;
    private String name;
    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override
    public boolean equals(Object obj) {
        if (this.id == ((Person)obj).id)
            return true;
        return false;
    }
}

public class Test {
    public static void main(String[] args) {
        Person person1 = new Person(1, "Lisa");
        Person person2 = new Person(1, "Lisa");
        HashMap<Person, Integer> persons = new HashMap<>();
        persons.put(person1, 10);
        System.out.println(persons.get(person2));
    }
}
null

String同時重寫了equals()方法和hashCode()方法

public class Test {
    public static void main(String[] args) {
        HashMap<String, Integer> strs = new HashMap<>();
        String str1 = new String("ddd");
        String str2 = new String("ddd");
        strs.put(str1, 10);
        System.out.println(strs.get(str2));
    }
}
10

參考
https://blog.csdn.net/changrj6/article/details/100043822

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末色建,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舌缤,更是在濱河造成了極大的恐慌,老刑警劉巖某残,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件国撵,死亡現(xiàn)場離奇詭異,居然都是意外死亡玻墅,警方通過查閱死者的電腦和手機介牙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澳厢,“玉大人环础,你說我怎么就攤上這事囚似。” “怎么了线得?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵饶唤,是天一觀的道長。 經(jīng)常有香客問我贯钩,道長募狂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任角雷,我火速辦了婚禮祸穷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘勺三。我一直安慰自己雷滚,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布吗坚。 她就那樣靜靜地躺著祈远,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刻蚯。 梳的紋絲不亂的頭發(fā)上绊含,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天,我揣著相機與錄音炊汹,去河邊找鬼躬充。 笑死,一個胖子當(dāng)著我的面吹牛讨便,可吹牛的內(nèi)容都是我干的充甚。 我是一名探鬼主播,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼霸褒,長吁一口氣:“原來是場噩夢啊……” “哼伴找!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起废菱,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤技矮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后殊轴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體衰倦,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年旁理,在試婚紗的時候發(fā)現(xiàn)自己被綠了樊零。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡孽文,死狀恐怖驻襟,靈堂內(nèi)的尸體忽然破棺而出夺艰,到底是詐尸還是另有隱情,我是刑警寧澤沉衣,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布郁副,位于F島的核電站,受9級特大地震影響厢蒜,放射性物質(zhì)發(fā)生泄漏霞势。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一斑鸦、第九天 我趴在偏房一處隱蔽的房頂上張望愕贡。 院中可真熱鬧,春花似錦巷屿、人聲如沸固以。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽憨琳。三九已至,卻和暖如春旬昭,著一層夾襖步出監(jiān)牢的瞬間篙螟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工问拘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留遍略,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓骤坐,卻偏偏與公主長得像绪杏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纽绍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355