為什麼重寫equals必須重寫hashCode的基礎分析 1.我們先來瞭解下原生的equals和hashCode代碼 原生equals:它判斷的是兩個對象是否相等 原生hashCode值:它是根據記憶體地址換算出來的一個整數類型的值 2.至於為什麼要重寫equals和hashCode? 當然為了滿足我 ...
為什麼重寫equals必須重寫hashCode的基礎分析
1.我們先來瞭解下原生的equals和hashCode代碼
原生equals:它判斷的是兩個對象是否相等
原生hashCode值:它是根據記憶體地址換算出來的一個整數類型的值
2.至於為什麼要重寫equals和hashCode?
當然為了滿足我們具體的業務需求啦,畢竟我們不一定只比較對象相等嘛
3.做一個超簡單小案例來理解下(包名不規範,切勿模仿);
(1)創建一個Student類,不重寫equals和hashCode
package 重寫equal必須重寫hashcode; public class Student { public String id; //學生的id public String name; //學生的名字 public Student() { super(); // TODO Auto-generated constructor stub } public String toString() { return id + ":" + name; } public Student(String id, String name) { super(); this.id = id; this.name = name; } }
(2)new一個hashSet,分別添加三個student
package 重寫equal必須重寫hashcode; import java.util.HashSet; public class Test { //學生ID和姓名都相同我們視為重覆 public static void main(String[] args) { HashSet hs = new HashSet(); hs.add(new Student("001","小明")); hs.add(new Student("002","小花")); hs.add(new Student("002","小花")); System.out.println(hs); } }
(3)運行結果如下:
(4)我們可以看到,信息出現了重覆;new的對象不同生成的hashCode值不同,所以hashSet會把三個Student對象當作不同的對象。
2.接下來我們重寫equals而不重寫hashCode
(1)重寫equals後代碼如下:
package 重寫equal必須重寫hashcode; public class Student { public String id; //學生的id public String name; //學生的名字 public Student() { super(); // TODO Auto-generated constructor stub } public String toString() { return id + ":" + name; } public Student(String id, String name) { super(); this.id = id; this.name = name; } public boolean equals(Object obj) { if(this == obj) { //判斷是否是同一對象 return true; //同一類型返回true(跟自己比較) } if(getClass()!=obj.getClass()) { //判斷是否為同一類型 return false; //不是同類型返回false(類型不同肯定為不同的對象) } Student stu = (Student)obj; //強制轉換成Student類型 boolean result = this.id.equals(stu.id); //判斷ID是否相等 return result; //返回判斷結果 } }
(2)現在我們運行下,結果如下圖:
(3)可以發現重覆的信息沒有刪除掉,可以判斷添加Student對象沒有調用equals方法,而是根據hashCode值的不同,hashSet就認為三個對象不相等。
3.最後我們重寫equals和hashCode;
(1)重寫hashCode;
package 重寫equal必須重寫hashcode; public class Student { public String id; //學生的id public String name; //學生的名字 public Student() { super(); // TODO Auto-generated constructor stub } public String toString() { return id + ":" + name; } public Student(String id, String name) { super(); this.id = id; this.name = name; } public boolean equals(Object obj) { if(this == obj) { //判斷是否是同一對象 return true; //同一類型返回true(跟自己比較) } if(getClass()!=obj.getClass()) { //判斷是否為同一類型 return false; //不是同類型返回false(類型不同肯定為不同的對象) } Student stu = (Student)obj; //強制轉換成Student類型 boolean result = this.id.equals(stu.id); //判斷ID是否相等 return result; //返回判斷結果 } public int hashCode() { //重寫hashCode return id.hashCode(); //返回ID屬性的哈希值 } }
(2)運行結果如下:
(3)是不是就把重覆的信息移除了呢?哈哈
如果有不妥之處,請各位大佬多多包涵,這些也是個人的理解
如果你有補充,歡迎留下你的意見在評論區!