java中重写equals()方法的时候为什么要重写hashCode()方法?
2016-09-29 15:06
771 查看
有时候,或许会听到被人说,在重写equals方法的时候,记得重写hashcode方法。那么自然有这样的疑问,那么为什么这样?equals方法和hashCode方法是什么关系?不重写的时候会有什么危害?文章将从一下几个方面进行叙述。
一:什么是hashCode(),equals()方法?
二:hashCode(),equals()两种方法是什么关系?
三:为什么在重写equals方法的时候要重写hashcode的方法?
四:怎么重写这两种方法?
一:什么是hashCode(),equals()方法?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201609/29/96d9a38e0598f77d70a0a028d71cd23e)
关于equals()方法,经常说的就是比较的是内容(与==比较的地址相对),这么说不完全对--看下面这段代码:
学生类:
主测试类:
我们想通过一个学生的学号以及姓名来判断是否是同一个学生。可是 根据程序的运行结果(打印出的为false)来看,即使是学号与姓名两个字段都完全的相同,判断出的学生也不是相同的。
equals()在java.lang.Object下,其源码为:
即在Object中equals方法只是判断的为是否为同一个对象的引用。
在String类中,我们可以这样写,打印的结果为true。
这里是因为在String类中对equals方法进行了重写的原因。
什么是hashcode方法?在java中,对对象的存储采取了存储在哈希表中处理方法,hashcode方法是根据对象的地址转换之后返回的一个哈希值,其详细的用法在这篇文章涉及的时候详细的介绍过-点击打开链接
二:hashCode(),equals()两种方法是什么关系?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201609/29/cc6e5b4eeac2326d5ae84c299f563085)
要弄清楚这两种方法的关系,就需要对哈希表有一个基本的认识。其基本的结构如下:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201609/29/572301ad41b01b416db689f99d05531e)
对于hashcode方法,会返回一个哈希值,哈希值对数组的长度取余后会确定一个存储的下标位置,如图中用数组括起来的第一列。
不同的哈希值取余之后的结果可能是相同的摸着时候就用equals方法判断是否为相同的对象,不同则在链表中插入。
则有:
hashcode不相同,用equals()方法判断的返回的一定为false。
hashcode相同,equals()方法返回值不能确认,可能为true,可能为false。
三:为什么在重写equals方法的时候要重写hashcode的方法?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201609/29/b091f58f00e2fa21f339554b779fa954)
上述了两种方法的关系之后,我们知道判断的时候先根据hashcode进行的判断,相同的情况下再根据equals()方法进行判断。如果只重写了equals方法,而不重写hashcode的方法,会造成hashcode的值不同,而equals()方法判断出来的结果为true。
在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了equals()的方法,而不重写hashcode的方法,Object中hashcode是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写hashcode方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。
四:怎么重写这两种方法?
![](https://oscdn.geek-share.com/Uploads/Images/Content/201609/29/381b2ceac01d3d0acd400a3875fe488c)
关于重写equals()方法应该满足的原则,这里就不在赘述。只是通过一个小例子来对其有一个重写两个方法有一个新的认识。
主测试方法类:
一:什么是hashCode(),equals()方法?
二:hashCode(),equals()两种方法是什么关系?
三:为什么在重写equals方法的时候要重写hashcode的方法?
四:怎么重写这两种方法?
一:什么是hashCode(),equals()方法?
关于equals()方法,经常说的就是比较的是内容(与==比较的地址相对),这么说不完全对--看下面这段代码:
学生类:
public class Student { private int id; private String name; public Student(int id, String name) { super(); this.id = id; this.name = name; } }
主测试类:
public class Test { public static void main(String[] args) { Student s1=new Student(001,"邵小二"); Student s2=new Student(001,"邵小二"); System.out.println(s1.equals(s2)); } }
我们想通过一个学生的学号以及姓名来判断是否是同一个学生。可是 根据程序的运行结果(打印出的为false)来看,即使是学号与姓名两个字段都完全的相同,判断出的学生也不是相同的。
equals()在java.lang.Object下,其源码为:
public boolean equals(Object obj) { return (this == obj); }
即在Object中equals方法只是判断的为是否为同一个对象的引用。
在String类中,我们可以这样写,打印的结果为true。
String str1="123"; String str2="123"; //print true System.out.println(str1.equals(str2));
这里是因为在String类中对equals方法进行了重写的原因。
什么是hashcode方法?在java中,对对象的存储采取了存储在哈希表中处理方法,hashcode方法是根据对象的地址转换之后返回的一个哈希值,其详细的用法在这篇文章涉及的时候详细的介绍过-点击打开链接
二:hashCode(),equals()两种方法是什么关系?
要弄清楚这两种方法的关系,就需要对哈希表有一个基本的认识。其基本的结构如下:
对于hashcode方法,会返回一个哈希值,哈希值对数组的长度取余后会确定一个存储的下标位置,如图中用数组括起来的第一列。
不同的哈希值取余之后的结果可能是相同的摸着时候就用equals方法判断是否为相同的对象,不同则在链表中插入。
则有:
hashcode不相同,用equals()方法判断的返回的一定为false。
hashcode相同,equals()方法返回值不能确认,可能为true,可能为false。
三:为什么在重写equals方法的时候要重写hashcode的方法?
上述了两种方法的关系之后,我们知道判断的时候先根据hashcode进行的判断,相同的情况下再根据equals()方法进行判断。如果只重写了equals方法,而不重写hashcode的方法,会造成hashcode的值不同,而equals()方法判断出来的结果为true。
在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了equals()的方法,而不重写hashcode的方法,Object中hashcode是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写hashcode方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。
四:怎么重写这两种方法?
关于重写equals()方法应该满足的原则,这里就不在赘述。只是通过一个小例子来对其有一个重写两个方法有一个新的认识。
public class SimpleDemo { // 部门 private String department; // 工号 private int id; public SimpleDemo(int id, String department) { super(); this.id = id; this.department = department; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getdepartment() { return department; } public void setdepartment(String department) { this.department = department; } @Override public int hashCode() { int hash = 1; hash = hash * 17 + id; hash = hash * 31 + department.hashCode(); return hash; } @Override public boolean equals(Object obj) { if (obj == null) return false; if (obj == this) return true; if (obj instanceof SimpleDemo) { SimpleDemo sd = (SimpleDemo) obj; return sd.department.equals(department) && sd.id == id; } return false; }
主测试方法类:
public class Test02 { public static void main(String[] args) { SimpleDemo sdo1=new SimpleDemo(0106,"技术部"); SimpleDemo sdo2=new SimpleDemo(0106,"技术部"); //print true System.out.println(sdo1.equals(sdo2)); } }
相关文章推荐
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- 建立一个对象模型的时候,为什么要重写hashCode与equals方法
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- java为什么要重写hashCode和equals方法
- 重写Java 的equals和hashcode方法的时候应该注意什么
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- JAVA中重写equals()方法为什么要重写hashcode()方法
- JAVA中重写equals()方法为什么要重写hashcode()方法说明
- 【Java基础】JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法说明