摘要:它也是用來(lái)判斷兩個(gè)對(duì)象是否相等,所以也得分不同的情況來(lái)說(shuō)明。什么是的作用是獲取哈希碼,也稱為散列碼它返回的一個(gè)整數(shù)。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。它定義在的中,這就意味著中的任何類都包含有函數(shù)。
前言
萬(wàn)丈高樓平地起,今天的聊點(diǎn)基礎(chǔ)而又經(jīng)常讓人忽視的話題,比如“==”與“equals()”區(qū)別?為何當(dāng)我們重寫完"equals()"后也要有必要去重寫"hashcode()"呢? ... 帶著這些問(wèn)題,我們一起來(lái)探究一下。
概念"==":它主要是判斷符號(hào)兩邊的“對(duì)象”的值是否相等,而這里的“值“”又有所區(qū)分了。
基礎(chǔ)數(shù)據(jù)類型:比較的就是自身的值,這個(gè)跟我們常規(guī)的理解是基本一致的。
引用數(shù)據(jù)類型:比較的對(duì)象的內(nèi)存地址。
“equals()”:它也是用來(lái)判斷兩個(gè)對(duì)象是否相等,所以也得分不同的情況來(lái)說(shuō)明。
在當(dāng)前類中,沒(méi)有重寫equals方法的話,默認(rèn)的實(shí)現(xiàn)跟"=="的實(shí)現(xiàn)是一樣的。下面是Object類的equals方法實(shí)現(xiàn)。
在當(dāng)前類中,重寫了equals方法,此時(shí)判斷的依據(jù)就是你重寫的邏輯。
怎樣重寫equals()方法?1、自反性:對(duì)于任何非空引用x,x.equals(x)應(yīng)該返回true。
2、對(duì)稱性:對(duì)于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也應(yīng)該返回true。
3、傳遞性:對(duì)于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也應(yīng)該返回true。
4、一致性:如果x和y引用的對(duì)象沒(méi)有發(fā)生變化,那么反復(fù)調(diào)用x.equals(y)應(yīng)該返回同樣的結(jié)果。
5、非空性:對(duì)于任意非空引用x,x.equals(null)應(yīng)該返回false。
由此可以看出,重寫一個(gè)equals()方法,需要注意的點(diǎn)還是比較多的,這里給出一個(gè)參考的事例。
public class EqualsDemo { private String name; private String info; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; EqualsDemo that = (EqualsDemo) o; if (name != null ? !name.equals(that.name) : that.name != null) return false; return info != null ? info.equals(that.info) : that.info == null; } @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; result = 31 * result + (info != null ? info.hashCode() : 0); return result; } }
有些讀者可能會(huì)感到奇怪,不是說(shuō)重寫equals()方法嗎,為什么這里又出現(xiàn)了一個(gè)hashcode()?所以這里又引出了我們的另一個(gè)主角hashcode()方法,當(dāng)我們重寫了equals()方法后,它就一定會(huì)出現(xiàn),也會(huì)“吵著“自己也要被重寫。
什么是hashcode()?hashCode() 的作用是獲取哈希碼,也稱為散列碼;它返回的一個(gè)int整數(shù)。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。hashCode方法的主要作用是為了配合基于散列的集合一起正常運(yùn)行,這樣的散列集合包括HashSet、HashMap、HashTable等。它定義在JDK的Object.java中,這就意味著Java中的任何類都包含有hashCode() 函數(shù)。
當(dāng)我們?cè)谏厦娴募喜迦雽?duì)象的時(shí)候,java是怎么知道里面是否有重復(fù)的對(duì)象呢?可能大家第一反應(yīng)是equals方法,沒(méi)錯(cuò)這方法可以實(shí)現(xiàn)這個(gè)功能,但是當(dāng)集合里面有成千上萬(wàn)個(gè)元素的時(shí)候,效率會(huì)如何呢?答案當(dāng)然是比較差了,所以才會(huì)出現(xiàn)了哈希碼。
public V put(K key, V value) { //判斷當(dāng)前數(shù)組是否等于{},若是則初始化數(shù)組 if (table == EMPTY_TABLE) { inflateTable(threshold); } //判斷 key 是否等于 null,是則將把當(dāng)前鍵值對(duì)添加進(jìn)table[0]中,遍歷table[0]鏈表 //如果已經(jīng)有null為key的Entry,則修改值,返回舊值,若無(wú)則直接添加。 if (key == null) return putForNullKey(value); //key不為null則計(jì)算hash int hash = hash(key); //搜索對(duì)應(yīng)hash所在的table中的索引 int i = indexFor(hash, table.length); for (Entrye = 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; } } //修改次數(shù) modCount++; addEntry(hash, key, value, i); return null; }
這里是jdk7中 Hashmap put()方法的實(shí)現(xiàn),通過(guò)源碼的注釋可以看出執(zhí)行的流程,需要更詳細(xì)的了解HashMap可以參考我之前發(fā)在開(kāi)源中國(guó)的博客《Java7 HashMap全面解讀! 》,鏈接:https://my.oschina.net/199212...
經(jīng)過(guò)概念的介紹,知道為什么重寫完equals()后要接著重寫hashcode()了吧?
People p1=new People("小明",18); People p2=new People("小明",18);
此時(shí)重寫了equals方法,p1.equals(p2)一定返回true,假如只重寫equals而不重寫hashcode,那么Student類的hashcode方法就是Object默認(rèn)的hashcode方法,由于默認(rèn)的hashcode方法是根據(jù)對(duì)象的內(nèi)存地址經(jīng)哈希算法得來(lái)的,顯然此時(shí)s1!=s2,故兩者的hashcode不一定相等。所以在一些集合的使用當(dāng)中會(huì)出現(xiàn)問(wèn)題。
總結(jié)小小的幾個(gè)方法,沒(méi)想到卻有這么多“坑”,而且在面試中也會(huì)經(jīng)常被問(wèn)到,在金三銀四的時(shí)候,但愿各位不會(huì)陷在這里。
喜歡的話,關(guān)注一下微信公眾號(hào)《深夜里的程序猿》,每天更新高質(zhì)量IT文章
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/77538.html
摘要:如果我們不重寫的方法,那么就會(huì)默認(rèn)調(diào)用的方法小王小王我們可以看到以上的運(yùn)行結(jié)果違背了的規(guī)定如果返回,那么方法必須返回相同的整數(shù)所以我們需要對(duì)對(duì)象的方法進(jìn)行重寫通過(guò)重寫讓其與對(duì)象的屬性關(guān)聯(lián)起來(lái),那么就能夠達(dá)到為,那么的值也相等。 面試官讓你說(shuō)說(shuō)==和equals()的區(qū)別,重寫equals必須重寫hashcode方法嗎 本身特質(zhì)來(lái)說(shuō) ==:操作符 equals():方法 適用...
摘要:介紹的作用是獲取哈希碼,也稱為散列碼它實(shí)際上是返回一個(gè)整數(shù)。所以具有相索引的對(duì)象,在該散列碼位置處存在多個(gè)對(duì)象,我們必須依靠的和本身來(lái)進(jìn)行區(qū)分。 1.hashCode介紹 hashCode() 的作用是獲取哈希碼,也稱為散列碼;它實(shí)際上是返回一個(gè)int整數(shù)。這個(gè)散列碼的作用是確定該對(duì)象在散列表中的索引位置,如果有看我的上一篇文章 什么是散列表,那么這里的散列碼就相當(dāng)于上文中根據(jù)首字母查...
摘要:無(wú)論在中出現(xiàn)什么,都可以認(rèn)為它是對(duì)象除了八大基本數(shù)據(jù)類型。讓當(dāng)前線程等待某個(gè)對(duì)象的鎖,當(dāng)然應(yīng)該通過(guò)這個(gè)對(duì)象來(lái)操作了。但是要注意的是方法調(diào)用后,被喚醒的線程不會(huì)立馬獲得到鎖對(duì)象。主要的區(qū)別在于在釋放同時(shí),釋放了對(duì)象鎖的控制。 前言 五一回家又?jǐn)喔艘粋€(gè)放假時(shí)間了~~~ 只有光頭才能變強(qiáng) 回顧前面: ThreadLocal就是這么簡(jiǎn)單 多線程三分鐘就可以入個(gè)門了! 多線程基礎(chǔ)必要知識(shí)點(diǎn)!...
摘要:更好的辦法把所有的都到緩沖池去吧最好在用到的時(shí)候就進(jìn)行這個(gè)操作然后就可以用比較兩個(gè)字符串的值了二簡(jiǎn)單數(shù)據(jù)類型和封裝類中的和為每一個(gè)簡(jiǎn)單數(shù)據(jù)類型提供了一個(gè)封裝類,每個(gè)基本數(shù)據(jù)類型可以封裝成對(duì)象類型。 值類型是存儲(chǔ)在內(nèi)存中的堆棧(以后簡(jiǎn)稱棧),而引用類型的變量在棧中僅僅是存儲(chǔ)引用類型變量的地址,而其本身則存儲(chǔ)在堆中。 ==操作比較的是兩個(gè)變量的值是否相等,對(duì)于引用型變量表示的是兩個(gè)變量...
摘要:集合判斷兩個(gè)元素的標(biāo)準(zhǔn)是兩個(gè)對(duì)象通過(guò)方法比較相等,并且兩個(gè)對(duì)象的方法返回值也相等。的集合元素也是有序的,以枚舉值在類內(nèi)的定義順序來(lái)決定集合元素的順序。是所有實(shí)現(xiàn)類中性能最好的,但它只能保存同一個(gè)枚舉類的枚舉值作為集合元素。 Set集合通常不能記住元素的添加順序。Set不允許包含重復(fù)的元素。 Set集合不允許包含相同的元素,如果試圖把兩個(gè)相同的元素加入同一個(gè)Set集合中,則添加操作...
閱讀 2996·2021-11-23 09:51
閱讀 2817·2021-11-11 16:55
閱讀 2926·2021-10-14 09:43
閱讀 1402·2021-09-23 11:22
閱讀 1044·2019-08-30 11:04
閱讀 1673·2019-08-29 11:10
閱讀 965·2019-08-27 10:56
閱讀 3115·2019-08-26 12:01