您好,登錄后才能下訂單哦!
這篇文章主要介紹為什么修改equals方法時還要重寫hashcode方法,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
雖然在實際開發中,我們已經使用到散列集合(如HashMap),或也單獨學過散列(Hash)。
但是也會有很多人像我一樣,看到有些時候別人寫的pojo中有對對象內hashcode函數做一個重寫,這就讓我重新思考為什么要這么做? 下面就讓我和你一起去探索一下吧!
Hash就是上文說到的散列,是把任意長度的輸入(又叫做預映射pre-image)通過散列算法變換成固定長度的輸出,該輸出就是散列值。它的理論時間復雜度是可以達到O(1),但一般來說,這個散列函數是極難設計的。說到散列值,就是通過散列函數轉化出來的:
如果兩個散列值是不一樣y(x1)!=y(x2),那么這兩個散列值的原始輸入一定是不一樣的。
如果兩個散列值出現了相等,那么并不代碼這兩個散列值的原始輸入一定是一樣的,可能是屬于哈希碰撞(不同關鍵字經過散列變換結果是一樣的的現象);
對于哈希函數有哪些我也不再介紹,想了解可以直接去查散列函數的。
很多情況下我們也許都會用到hash表來做提高查詢效率,那么這個hash表是如何提高效率的?其實就是基于上面所說的散列函數,根據設計的散列函數,我們對于每一個關鍵字都有唯一的散列值,那么就能夠直接根據這個散列值直接就能找到元素在集合中的位置,從而獲得其值,這對于集合的一個個對象進行比較來說,是提高了很多的。
通過以上操作,我們很容易就能理解為啥散列技術在查詢的復雜度是能達到O(1).
但是一般來說java都會內置了hashcode的實現,那為什么在寫對象的時候,只要對equals進行重寫,都推薦對hashcode進行重寫呢?
看HashCode的常規協定:
在 Java 應用程序執行期間,在同一對象上多次調用 hashCode 方法時,必須一致地返回相同的整數,前提是對象上 equals 比較中所用的信息沒有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。
如果根據 equals(Object) 方法,兩個對象是相等的,那么在兩個對象中的每個對象上調用 hashCode 方法都必須生成相同的整數結果。
以下情況不 是必需的:
如果根據 equals(java.lang.Object) 方法,兩個對象不相等,那么在兩個對象中的任一對象上調用 hashCode 方法必定會生成不同的整數結果。但是,程序員應該知道,為不相等的對象生成不同整數結果可以提高哈希表的性能。
實際上,由 Object 類定義的 hashCode 方法確實會針對不同的對象返回不同的整數。(這一般是通過將該對象的內部地址轉換成一個整數來實現的,但是 JavaTM 編程語言不需要這種實現技巧。)
當equals方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,該協定聲明相等對象必須具有相等的哈希碼。
根據以上知道,java內部的一個實現是以地址來的,如果對equals進行重寫了,也就是對象你判斷相等時不再以java提供的方法,那么將來在使用hash表的時候,就會存在equals是相等的,但hashcode卻是不相等的!
所以建議:在修改equals的方法時,記得修改hashcode方法!!!
下面做個小例子
/** * @author: Kilig * @date: 2020/6/22 21:18 * @description: */ public class User { private int id; public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User)) return false; User user = (User) o; return getId() == user.getId(); } // @Override // public int hashCode() { // return Objects.hash(getId()); // } }
public static void main(String[] args) { User a=new User(); User b=new User(); a.setId(1); b.setId(1); System.out.println(a.equals(b)); System.out.println(a.hashCode() == b.hashCode()); }
運行結果
個人經驗,希望能給大家一個參考,也希望大家多多支持億速云。
以上是“為什么修改equals方法時還要重寫hashcode方法”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。