弄懂java中”==“、”equals“捆毫、”hashCode“

最近在讀《Effective Java》里面有很著名的一個(gè)重寫(xiě)equals和hashcode的論斷。并介紹了重寫(xiě)的原則冲甘。今天我來(lái)說(shuō)一下面試題中經(jīng)常出現(xiàn)但是我們一般理解不夠深刻的”=“绩卤、”equals“、”hsahcode“區(qū)別和聯(lián)系江醇。

基本概念

1 “==”

在java中“==”是用來(lái)比較變量值是否相等濒憋。如果是基本類(lèi)型,直接比較值陶夜。如果是對(duì)象類(lèi)型凛驮,比較的是兩個(gè)對(duì)象的引用,也就是地址条辟。對(duì)象是放在堆中的黔夭,棧中存放的是對(duì)象的引用∮鸬眨“==”是對(duì)棧中的值進(jìn)行比較的本姥。

2 “equals”

我們都知道java所有的類(lèi)都是集成自O(shè)bject類(lèi),Object里有一個(gè)方法“equals”杭棵,這個(gè)方法是用來(lái)比較兩個(gè)對(duì)象是否相等的婚惫。在Object類(lèi)中有這樣的代碼:

public boolean equals(Object o) {
return this == o;
}

說(shuō)明在Object里"equals"和"=="是一回事。

3 “hashcode”

在Object里提供了hashcode這個(gè)方法。要說(shuō)hashcode就得說(shuō)java集合辰妙。java有的集合是不能重復(fù)的鹰祸,所以需要用equeals判斷集合中元素是否是同一個(gè)。但是如果集合中現(xiàn)在已經(jīng)有1000個(gè)元素密浑,那么第1001個(gè)元素加入集合時(shí)蛙婴,它就要調(diào)用1000次equals方法。這顯然會(huì)大大降低效率尔破。于是街图,Java采用了哈希表的原理。哈希(Hash)實(shí)際上是個(gè)人名懒构,由于他提出一哈希算法的概念餐济,所以就以他的名字命名了。哈希算法也稱(chēng)為散列算法胆剧,是將數(shù)據(jù)依特定算法直接指定到一個(gè)地址上絮姆。可以說(shuō)hashCode方法實(shí)際上返回的就是對(duì)象存儲(chǔ)的物理地址(實(shí)際可能并不是)秩霍。這樣一來(lái)篙悯,當(dāng)集合要添加新的元素時(shí),先調(diào)用這個(gè)元素的hashCode方法铃绒,就一下子能定位到它應(yīng)該放置的物理位置上鸽照。如果這個(gè)位置上沒(méi)有元素,它就可以直接存儲(chǔ)在這個(gè)位置上颠悬,不用再進(jìn)行任何比較了矮燎;如果這個(gè)位置上已經(jīng)有元素了,就調(diào)用它的equals方法與新元素進(jìn)行比較赔癌,相同的話就不存了诞外,不相同就散列其它的地址。

關(guān)系

首先說(shuō)“==”和“equals”灾票。
先明白一個(gè)事情:如果類(lèi)沒(méi)有重寫(xiě)equals浅乔,那么對(duì)于該類(lèi)的對(duì)象來(lái)說(shuō)“==”和“equals”沒(méi)有區(qū)別。都是比較對(duì)象的內(nèi)存地址铝条。 但在一些類(lèi)庫(kù)當(dāng)中這個(gè)方法被覆蓋掉了靖苇,如String,Integer,Date在這些類(lèi)當(dāng)中equals有其自身的實(shí)現(xiàn),而不再是比較類(lèi)在堆內(nèi)存中的存放地址了班缰。所以會(huì)有很多經(jīng)典的面試題:

String a = new String ("abc");
String b = new String ("abc");
System.out.println(a.equals(b));
System.out.println(a==b);

結(jié)果大家都知道 是true和false贤壁,其實(shí)這才是特殊情況。并不能得出一般的結(jié)論而籠統(tǒng)的說(shuō):”equals比較對(duì)象值埠忘,'=='比較地址“脾拆。要看是否重寫(xiě)了equals方法馒索。再說(shuō)equals和hashCode之間的關(guān)系。首先hashCode存在就是為了提高效率并且輔助equals的名船,一般重寫(xiě)equals要同時(shí)重寫(xiě)hashCode绰上。java中這樣規(guī)定他們的關(guān)系:1、如果兩個(gè)對(duì)象相同渠驼,那么它們的hashCode值一定要相同蜈块;2、如果兩個(gè)對(duì)象的hashCode相同迷扇,它們并不一定相同 百揭,上面說(shuō)的對(duì)象相同指的是用eqauls方法比較。反過(guò)來(lái):hashcode()不等蜓席,一定能推出equals()也不等器一;hashcode()相等,equals()可能相等厨内,也可能不等祈秕。 如果重寫(xiě)這兩個(gè)方法最好遵循以上原則。所以比較兩者還要看具體是如何重寫(xiě)的雏胃。

特殊情況

說(shuō)一種特殊情況:

String s1 = "Lpnpcs";
String s2 = "Lpnpcs";
if (s1 == s2) {
System.out.println("s1 == s2");
} else{
System.out.println("s1 != s2");
}輸出s1==s2踢步;
String s1 = "Lpnpcs";
String s2 = new String("Lpnpcs");
if (s1 == s2)
{System.out.println("s1 == s2");}
else
{System.out.println("s1 != s2");}
if (s1.equals(s2)) {System.out.println("s1 equals s2");}
else{
System.out.println("s1 not equals s2");
}

輸出s1 != s2 s1 equals s2說(shuō)明:s1 s2分別引用了兩個(gè)"Lpnpcs"String對(duì)象。這是什么情況丑掺? 這是由于java中對(duì)于字符串定義了一個(gè)字符串緩沖池,程序在運(yùn)行的時(shí)候會(huì)創(chuàng)建一個(gè)字符串緩沖池當(dāng)使用 s2 = "Lpnpcs" 這樣的表達(dá)是創(chuàng)建字符串的時(shí)候述雾,程序首先會(huì)在這個(gè)String緩沖池中尋找相同值的對(duì)象街州,在第一個(gè)程序中,s1先被放到了池中玻孟,所以在s2被創(chuàng)建的時(shí)候唆缴,程序找到了具有相同值的 s1將s2引用s1所引用的對(duì)象"Lpnpcs"。第二段程序中黍翎,使用了 new 操作符面徽,他明白的告訴程序:"我需要新建一個(gè)新的"于是一個(gè)新的"Lpnpcs"String對(duì)象被創(chuàng)建在內(nèi)存中。他們的值相同匣掸,但是位置不同趟紊。所以可見(jiàn)java定義這個(gè)緩沖池就是為了節(jié)約資源。我們?cè)谟米址臅r(shí)候 盡量采用 :String a =“”碰酝;這種形式霎匈。以上就是他們的實(shí)現(xiàn)和原理,相信現(xiàn)在應(yīng)該很清楚了送爸。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铛嘱,一起剝皮案震驚了整個(gè)濱河市暖释,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌墨吓,老刑警劉巖球匕,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異帖烘,居然都是意外死亡亮曹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)蚓让,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)乾忱,“玉大人,你說(shuō)我怎么就攤上這事历极≌粒” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵趟卸,是天一觀的道長(zhǎng)蹄葱。 經(jīng)常有香客問(wèn)我,道長(zhǎng)锄列,這世上最難降的妖魔是什么图云? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮邻邮,結(jié)果婚禮上竣况,老公的妹妹穿的比我還像新娘。我一直安慰自己筒严,他們只是感情好丹泉,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著鸭蛙,像睡著了一般摹恨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上娶视,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天晒哄,我揣著相機(jī)與錄音,去河邊找鬼肪获。 笑死寝凌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的孝赫。 我是一名探鬼主播硫兰,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼寒锚!你這毒婦竟也來(lái)了劫映?” 一聲冷哼從身側(cè)響起违孝,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泳赋,沒(méi)想到半個(gè)月后雌桑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡祖今,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年校坑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片千诬。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡耍目,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出徐绑,到底是詐尸還是另有隱情邪驮,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布傲茄,位于F島的核電站毅访,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盘榨。R本人自食惡果不足惜喻粹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望草巡。 院中可真熱鬧守呜,春花似錦、人聲如沸山憨。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萍歉。三九已至,卻和暖如春档桃,著一層夾襖步出監(jiān)牢的瞬間枪孩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工藻肄, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔑舞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓嘹屯,卻偏偏與公主長(zhǎng)得像攻询,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子州弟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

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