java中重写equals方法要重写hashCode方法
来源:互联网 发布:水泥凝结时间测定数据 编辑:程序博客网 时间:2024/06/05 17:38
在java笔试和面试中,经常会遇到“重写equals方法是否要重写hashCode方法“的问题。正好最近看到《effective java》中的这个地方,标题就是“覆盖equals方法总要覆盖hashCode方法”。
先看代码,本地也写了个demo,创建一个对象,先不重写hashCode方法,然后结合基于散列的集合使用,对于满足equals方法的相等的对象,看是否真的是相等的对象。
这段代码没有重写hashCode方法:
class TestObj {int i, j;public int getI() {return i;}public void setI(int i) {this.i = i;}public int getJ() {return j;}public void setJ(int j) {this.j = j;}TestObj(int i, int j) {super();this.i = i;this.j = j;}@Overridepublic boolean equals(Object obj) {if (this == obj){return true;}if (obj == null){return false;}if(!(obj instanceof TestObj)){return false;}TestObj other = (TestObj) obj;if (i == other.i && j == other.j){return true;}return true;}}接下来我们使用这个TestObj对象,书写一个测试类:
@Test public void Test1(){ Map<TestObj, String> map = new HashMap<TestObj, String>();TestObj t1 = new TestObj(1, 2);TestObj t2 = new TestObj(1, 2);map.put(t1, "obj");System.out.println(t1.equals(t2));System.out.println("t1-->" + t1.hashCode());System.out.println("t1-->" + t2.hashCode());System.out.println(map.get(t2)); }
控制台输出结果是“true”、“null”。t1和t2是满足equals方法的相同的对象,由于没有重写hashCode方法,打印出来的hashCode的值也不同,对象的散列码不同,从而获取的值为空。下面把这个类的hashCode的方法重写,如下:
@Overridepublic int hashCode() {final int f = 31;int result = 1;result = f * result + i;result = f * result + j;return result;}添加了重写hashCode方法后,在运行控制台输出的结果是“true”、“obj”。此时是真正意义的相等,相等的对象实例具有相同的散列码。
在Object规范中,有这样的判定描述:
1、在应用程序的执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这同一个对象调用多次,hashCode方法都必须始终如一的返回同一个整数。在一个应用程序的多次执行过程中,每次执行所返回的整数可以不一致。
2、如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode方法都必须产生同样的整数结果。
3、如果两个对象根据equals(Object)方法比较是不相等的,那么调用这两个对象中任意一个对象的hashCode方法,则不一定要产生不同的整数结果。
由此可见,在没有重写hashCode方法,即使实例对象equals方法是相等的,由于两者的hashCode值不同,所两个实例对象并不是相等的,所以获取到的值是为空。只有在重写了hashCode后,能够获取到对应的value值。
又写了一个Test2,此时是TestObj类是没有重写hashCode方法的,在map的添加角度也可以看出,代码如下:
@Test public void Test2(){ Map<TestObj, String> map = new HashMap<TestObj, String>();TestObj t1 = new TestObj(1, 2);TestObj t2 = new TestObj(1, 2);map.put(t1, "obj");map.put(t2, "obj2");System.out.println(t1.equals(t2));System.out.println("t1-->" + t1.hashCode());System.out.println("t1-->" + t2.hashCode());System.out.println(map.get(t2));System.out.println(map.size()); }
我们知道map集合的key是唯一的,即使在添加相同的key,map只会覆盖最后一次添加key对应的value值。上面的案例,没有重写TestObj类的hashCode方法,控制台的输出依次是“true”、“t1-->1245607833”、“t1-->1260258275”、“obj2”、“2”,可以看出,map集合是人为两个对象并不相等,对于hashCode可以看出,确实不相等,所以打印出来的长度为2.
接下来加上TestObj类的hashCode方法,这是打印的两者的hashCode值是相等的,map的长度是1。这样就对了,两个相等的对象,map添加是取最后一次对应value值。
理论上来说,在比较对象是否相等时,是先比较两者的hashCode值相等,如果hashCode的值相等,那么两个对象是相等的,相反,hashCode值不等,两个对象也就不等。当然,这个要看你的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中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- JAVA中重写equals()方法为什么要重写hashcode()方法?
- java中重写equals方法要重写hashCode方法
- java中重写equals和hashCode方法
- Java中equals和hashcode方法重写
- Java中HashSet要重写equals方法和hashCode方法
- 学生成绩管理系统
- 华为交换机关闭Telnet、开启SSH服务命令
- 7.创建对象时该用"()"还是"{}"?
- Java线程的5种状态及切换
- is expected to be of type but was actually of type 'com.sun.proxy.$Proxy70'
- java中重写equals方法要重写hashCode方法
- html5 canvas图片缩放,拖拽
- Intellij idea编写代码如何在方法之间加入一条分割线
- HashMap工作原理
- mysql集群技术:主从复制,读写分离
- h5标题和列表的学习
- 【转】Centos7.3防火墙配置
- go语言基础
- SpringMVC+Mybatis 多数据源配置