为什么重写equals一定要重写hashCode?
大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白,以下是我的一些个人理解。
这是Object类关于这两个方法的源码,可以看出,Object类默认的equals比较规则就是比较两个对象的内存地址。而hashcode是本地方法,java的内存是安全的,因此无法根据散列码得到对象的内存地址,但实际上,hashcode是根据对象的内存地址经哈希算法得来的。
public native int hashCode();
public boolean equals(Object paramObject){
return (this==paramObject);
}
上图展示了Student类的重写后的equals方法和hashcode方法,建议大家用eclipse自动生成,尽量不要自己敲因为很有可能会出错。
现在有两个Student对象:
Student s1=new Student("小明",18);
Student s2=new Student("小明",18);
此时s1.equals(s2)一定返回true
/*
*
*
* equals的使用
*
* */
package com.tinaluo.java; import java.awt.Color; class Cat {
private String name;
private int age;
private double weight;
private Color color; public Cat(String name, int age, double weight, Color color) {
this.name = name;
this.age = age;
this.weight = weight;
this.color = color;
} /*
* equals改写后必须重写hashCode()方法,对象相同则hashCode必须相同!
* 1、equals()相同,则hashCode必须相等
* 2、hashCode不相同等,则equals()必不相等
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if(this==obj){
return true;
}
if(obj==null){
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Cat cat = (Cat) obj;
return name.equals(cat.name) && (age == cat.age)
&& (weight == cat.weight) && (color.equals(cat.color));
}
} public class InternalLoad {
public static void main(String[] args) {
Cat a = new Cat("java", 12, 21, Color.BLACK);
Cat b = new Cat("C++", 12, 21, Color.WHITE);
Cat c = new Cat("java", 12, 21, Color.BLACK);
System.out.println(a.equals(b));
System.out.println(a.equals(c));
System.out.println(a.hashCode() == c.hashCode());
}
}
假如只重写equals而不重写hashcode,那么Student类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故两者的hashcode不一定相等。
然而重写了equals,且s1.equals(s2)返回true,根据hashcode的规则,两个对象相等其哈希值一定相等,所以矛盾就产生了,因此重写equals一定要重写hashcode,而且从Student类重写后的hashcode方法中可以看出,重写后返回的新的哈希值与Student的两个属性有关。
以下是关于hashcode的一些规定:
关键结论:
两个对象相等,hashcode一定相等
两个对象不等,hashcode不一定不等
hashcode相等,两个对象不一定相等
hashcode不等,两个对象一定不等
为什么重写equals一定要重写hashCode?的更多相关文章
- 为什么重写equals时必须重写hashCode方法?(转发+整理)
为什么重写equals时必须重写hashCode方法? 原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html ...
- 为什么重写 equals 方法 必须重写 hashCode
自己学到这,就记录了下来,代码都是自己敲得,有不对的地方希望大神指点出来 为什么重写 equals 方法 必须重写 hashCode 如果你重写了equals,比如说是基于对象的内容实现的,而不重写 ...
- 讲解:为什么重写equals时必须重写hashCode方法
一 :string类型的==和equals的区别: 结论:"=="是判断两个字符串的内存地址是否相等,equals是比较两个字符串的值是否相等,具体就不做扩展了,有兴趣的同学可以去 ...
- 为什么重写equals后要重写hashCode
equals和hashCode的关系 要搞清楚题目中的问题就必须搞明白equals方法和hashCode方法分别是什么,和诞生的原因,当搞明白了这一点其实题目就不算是个问题了,下面我们来探讨分别探讨一 ...
- java中为什么重写equals时必须重写hashCode方法?
在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCod ...
- 为什么重写equals一定要重写hashCode方法?
大家都知道,equals和hashcode是java.lang.Object类的两个重要的方法,在实际应用中常常需要重写这两个方法,但至于为什么重写这两个方法很多人都搞不明白. 下面我们看下Objec ...
- java 中为什么重写 equals 后需要重写 hashCode
本文为博主原创,未经允许不得转载: 1. equals 和 hashCode 方法之间的关系 这两个方法都是 Object 的方法,意味着 若一个对象在没有重写 这两个方法时,都会默认采用 Objec ...
- 编写高质量代码改善C#程序的157个建议——建议12: 重写Equals时也要重写GetHashCode
建议12: 重写Equals时也要重写GetHashCode 除非考虑到自定义类型会被用作基于散列的集合的键值:否则,不建议重写Equals方法,因为这会带来一系列的问题. 如果编译上一个建议中的Pe ...
- 为什么重写equals时必须重写hashCode方法?
原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现Stri ...
随机推荐
- CSRF总结
一.CSRF概述 CSRF跨站请求伪造,2007年被列为互联网20大安全隐患之一. 什么是跨站请求伪造?CSRF或XSRF 挟制用户在当前已经登录的web应用程序上执行非本意的操作的攻击方法.攻击者盗 ...
- win10卸载IE11后从新安装
win10卸载IE11后想要从新安装,运气不好的话各种坑安装不上,运气好就不说了.这里笔者在知乎看到一种方法,亲测可用,记录如下: 设置--应用--应用和功能--管理可选功能--添加功能--Inter ...
- 简单的页面互点Javascript代码
简单的页面互点Javascript代码,可以适用于前端$(function(){ $('.ip_b_con_item li,.pro_index_list li').mouseover(functio ...
- 生成式对抗网络(GAN)实战——书法字体生成练习赛
https://www.tinymind.cn/competitions/ai 生成式对抗网络(GAN)是近年来大热的深度学习模型. 目前GAN最常使用的场景就是图像生成,作为一种优秀的生成式模型,G ...
- pandas的一些
在具体谈及骚操作之前先捋一遍基本的统计特征函数 方法名 函数功能 所属库 sum() 计算数据样本的综合(按照列计算) pandas mean() 计算数据样本的算术平均数 pandas var() ...
- 按enter 导致整个页面刷新的解决办法
1.如果用的又from表单的存在,则在form中添加事件 <form onsubmit="return false;">.......</form> 2.增 ...
- jquery点击回到顶部
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- linux-kernel-4.4 移植 (2)解决上部遗留DMA-PL330的问题
查看drivers/tty/serial/samsung.c文件发现,当传输数据量小于ourport->min_dma_size时,不使用DMA,大于等于min_mda_size时才是使用DMA ...
- python3下获取全局坐标
前段时间自己想用python写一个关于截屏翻译的小功能,所以首先需要获取鼠标的坐标动作有按下.拖拽.释放.查找了很多资料无非是pyhook或者用其他语言重写.但是自己用的是python3.65,第三方 ...
- maven项目引用时,导入类报错,选择两个项目同时执行Maven update
maven项目引用时,导入类报错,选择两个项目同时执行Maven update springboot引入第三方jar,需要扫描时加@ComponentScan("第三方的包名") ...