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