Java基礎(chǔ)之hashCode()方法

一、概述

hashCode()方法定義在Object類中芯砸,其源碼為:
public native int hashCode();
由該方法的聲明可知:該方法為一個(gè)Native方法,返回值為int類型斋日,在Object類中并沒有具體的實(shí)現(xiàn)甸怕。為什么Object類中要定義一個(gè)這樣的方法缩多?它的作用是什么?

二峰尝、作用

對(duì)于集合類(容器類)的程序設(shè)計(jì)語言來說偏窝,基本都會(huì)用到hashCode(哈希值),在Java中,hashCode()方法的主要作用是是基于散列的集合正確存取囚枪,如HashSet派诬、HashMap、HashTable链沼。我們可以通過java.util.HashMap的中put方法的具體實(shí)現(xiàn):

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        } 
        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

put方法是用來向HashMap中添加新的元素默赂,從put方法的具體實(shí)現(xiàn)可知,會(huì)先調(diào)用hashCode方法得到該元素的hashCode()方法得到該元素的哈希值括勺,HashMap在具體實(shí)現(xiàn)中會(huì)用一個(gè)table保存已經(jīng)存進(jìn)去的元素的hashcode值缆八,然后查看table中是否存在該hashCode值,如果存在則調(diào)用equals方法重新確定是否存在該元素疾捍,如果存在奈辰,則更新value值,否則將新的元素添加到HashMap中乱豆,不相同就散列其它的地址奖恰。從這里可以看出,hashCode方法的存在是為了減少equals方法的調(diào)用次數(shù)宛裕,從而提高程序效率瑟啃。說通俗一點(diǎn):Java中的hashCode方法就是根據(jù)一定的規(guī)則將與對(duì)象相關(guān)的信息(比如對(duì)象的存儲(chǔ)地址,對(duì)象的字段等)映射成一個(gè)數(shù)值揩尸,這個(gè)數(shù)值稱作為散列值蛹屿。

三、hashCode()方法和equals()方法

對(duì)于兩個(gè)對(duì)象:

  • 如果調(diào)用equals方法得到的結(jié)果為true岩榆,則兩個(gè)對(duì)象的hashcode值必定相等错负;
  • 如果equals方法得到的結(jié)果為false,則兩個(gè)對(duì)象的hashcode值不一定不同勇边;
  • 如果兩個(gè)對(duì)象的hashcode值不等犹撒,則equals方法得到的結(jié)果必定為false;
  • 如果兩個(gè)對(duì)象的hashcode值相等粒褒,則equals方法得到的結(jié)果未知油航。

四、原則

我們?cè)谠O(shè)計(jì)一個(gè)類的時(shí)候怀浆,有時(shí)候需要重寫equals()方法,比如String類就重寫了Object類的equals()方法谊囚,來比較兩個(gè)字符串是否相等。
但重寫equals()方法時(shí)执赡,有一個(gè)原則:那就是必須覆寫hashCode()方法镰踏,讓equals方法和hashCode方法始終在邏輯上保持一致性。
《Effective Java》一書對(duì)hashCode()方法有這樣一段描述:

  • 在程序執(zhí)行期間沙合,只要equals方法的比較操作用到的信息沒有被修改奠伪,那么對(duì)這同一個(gè)對(duì)象調(diào)用多次,hashCode方法必須始終如一地返回同一個(gè)整數(shù);
  • 如果兩個(gè)對(duì)象根據(jù)equals方法比較是相等的,那么調(diào)用兩個(gè)對(duì)象的hashCode方法必須返回相同的整數(shù)結(jié)果;
  • 如果兩個(gè)對(duì)象根據(jù)equals方法比較是不等的绊率,則hashCode方法不一定得返回不同的整數(shù);
    其中第一條可以這樣理解:設(shè)計(jì)hashCode()時(shí)最重要的因素就是:無論何時(shí)谨敛,對(duì)同一個(gè)對(duì)象調(diào)用hashCode()都應(yīng)該產(chǎn)生同樣的值。如果在講一個(gè)對(duì)象用put()添加進(jìn)HashMap時(shí)產(chǎn)生一個(gè)hashCdoe值滤否,而用get()取出時(shí)卻產(chǎn)生了另一個(gè)hashCode值脸狸,那么就無法獲取該對(duì)象了。所以如果你的hashCode方法依賴于對(duì)象中易變的數(shù)據(jù)藐俺,用戶就要當(dāng)心了炊甲,因?yàn)榇藬?shù)據(jù)發(fā)生變化時(shí),hashCode()方法就會(huì)生成一個(gè)不同的散列碼欲芹。因此卿啡,在設(shè)計(jì)hashCode方法和equals方法的時(shí)候,如果對(duì)象中的數(shù)據(jù)易變菱父,則最好在equals方法和hashCode方法中不要依賴于該字段颈娜。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市浙宜,隨后出現(xiàn)的幾起案子揭鳞,更是在濱河造成了極大的恐慌,老刑警劉巖梆奈,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異称开,居然都是意外死亡亩钟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門鳖轰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來清酥,“玉大人,你說我怎么就攤上這事蕴侣⊙媲幔” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵昆雀,是天一觀的道長(zhǎng)辱志。 經(jīng)常有香客問我,道長(zhǎng)狞膘,這世上最難降的妖魔是什么揩懒? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮挽封,結(jié)果婚禮上已球,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好智亮,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布忆某。 她就那樣靜靜地躺著,像睡著了一般阔蛉。 火紅的嫁衣襯著肌膚如雪弃舒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天馍忽,我揣著相機(jī)與錄音棒坏,去河邊找鬼。 笑死遭笋,一個(gè)胖子當(dāng)著我的面吹牛坝冕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播瓦呼,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼喂窟,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了央串?” 一聲冷哼從身側(cè)響起磨澡,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎质和,沒想到半個(gè)月后稳摄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饲宿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年厦酬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘫想。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡仗阅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出国夜,到底是詐尸還是另有隱情减噪,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布车吹,位于F島的核電站筹裕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏窄驹。R本人自食惡果不足惜饶碘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望馒吴。 院中可真熱鬧扎运,春花似錦瑟曲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至负拟,卻和暖如春烦衣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背掩浙。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工花吟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人厨姚。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓衅澈,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親谬墙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子今布,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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

  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 1,155評(píng)論 0 16
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法拭抬,類相關(guān)的語法部默,內(nèi)部類的語法,繼承相關(guān)的語法造虎,異常的語法傅蹂,線程的語...
    子非魚_t_閱讀 31,597評(píng)論 18 399
  • java筆記第一天 == 和 equals ==比較的比較的是兩個(gè)變量的值是否相等,對(duì)于引用型變量表示的是兩個(gè)變量...
    jmychou閱讀 1,488評(píng)論 0 3
  • 一、基本數(shù)據(jù)類型 注釋 單行注釋:// 區(qū)域注釋:/* */ 文檔注釋:/** */ 數(shù)值 對(duì)于byte類型而言...
    龍貓小爺閱讀 4,257評(píng)論 0 16
  • 得到后再失去還是比從未得到過要好吧波桩。確切感受過擁有一樣事物是怎樣一種實(shí)實(shí)在在的感觸戒努,即便失去了這樣事物這種感觸也能...
    你的溫柔騫閱讀 451評(píng)論 0 0