為什麼重寫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)運作結果如下:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SYwIDM4UDO2MGZygzNwAzMmJGZyMjYxEzYhlDZ4kzMi9CX3AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL3M3Lc9CX6MHc0RHaiojIsJye.png)
(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)現在我們運作下,結果如下圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISPrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdsATOfd3bkFGazxCMx8VesATMfhHLlN3XnxCMwEzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5SYwIDM4UDO2MGZygzNwAzMmJGZyMjYxEzYhlDZ4kzMi9CX3AzLchDMxIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjL3M3Lc9CX6MHc0RHaiojIsJye.png)
(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)是不是就把重複的資訊移除了呢?哈哈
如果有不妥之處,請各位大佬多多包涵,這些也是個人的了解
如果你有補充,歡迎留下你的意見在評論區!