萬丈高樓平地起,今天的聊點基礎而又常常讓人忽視的話題,好比「==」與「equals()」區別?爲什麼當咱們重寫完"equals()"後也要有必要去重寫"hashcode()"呢? ... 帶着這些問題,咱們一塊兒來探究一下。java
"==":它主要是判斷符號兩邊的「對象」的值是否相等,而這裏的「值「」又有所區分了。面試
基礎數據類型:比較的就是自身的值,這個跟咱們常規的理解是基本一致的。算法
引用數據類型:比較的對象的內存地址。數組
「equals()」:它也是用來判斷兩個對象是否相等,因此也得分不一樣的狀況來講明。微信
在當前類中,沒有重寫equals方法的話,默認的實現跟"=="的實現是同樣的。下面是Object類的equals方法實現。ide
在當前類中,重寫了equals方法,此時判斷的依據就是你重寫的邏輯。函數
由此能夠看出,重寫一個equals()方法,須要注意的點仍是比較多的,這裏給出一個參考的事例。this
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()方法後,它就必定會出現,也會「吵着「本身也要被重寫。spa
hashCode() 的做用是獲取哈希碼,也稱爲散列碼;它返回的一個int整數。這個哈希碼的做用是肯定該對象在哈希表中的索引位置。hashCode方法的主要做用是爲了配合基於散列的集合一塊兒正常運行,這樣的散列集合包括HashSet、HashMap、HashTable等。它定義在JDK的Object.java中,這就意味着Java中的任何類都包含有hashCode() 函數。.net
當咱們在上面的集合插入對象的時候,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 (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; }
這裏是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文章