为什么重写equals()必须重写hashCode()
主要原因是因为hashCode是用对象的内部地址转换成一个整数的,而equals比较得是两个对象,或者是两个对象的内容
如果你重写了equals,而保留hashCode的实现不变,那么很可能两个对象明明相等,但是hashCode却不一样,这样,当其中一个最为键保存到hashMap等上面,就会出现hashCode不一样,则找不到.
看看String中equals和HashCode方法
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
} public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count; for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写
hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode确实不相同的
由于为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的
次数,这对比需要比较的数量很大的效率提高是很明显的,一个很好的例子就是在集合中的使用;
我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,但靠equals方法一样比较的
话,如果原来集合中以后又10000个元素了,那么放入10001个元素,难道要将前面的所有元素都进行比较,看看是否有重复,欧码噶的,这个效率可想而知,因此hashcode
就应遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据
只要看对应的hashcode地址上是否有值,那么就用equals比较,如果没有则直接插入,只要就大大减少了equals的使用次数,执行效率就大大提高了。
对象内容的比较才是设计equals()的真正目的,Java语言对equals()的要求如下,这些要求是必须遵循的。否则,你就不该浪费时间:
•对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是“true”。
•反射性:x.equals(x)必须返回是“true”。
•类推性:如果x.equals(y)返回是“true”,而且y.equals(z)返回是“true”,那么z.equals(x)也应该返回是“true”。
•还有一致性:如果x.equals(y)返回是“true”,只要x和y内容一直不变,不管你重复x.equals(y)多少次,返回都是“true”。
•任何情况下,x.equals(null),永远返回是“false”;x.equals(和x不同类型的对象)永远返回是“false”。
hashCode()的返回值和equals()的关系如下:
•如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。
•如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。
为什么重写equals()必须重写hashCode()的更多相关文章
- 为什么重写equals还要重写hashcode??
equals和hashcode是object类下一个重要的方法,而object类是所有类的父类,所以所有的类都有这两个方法 equals和hashcode间的关系: 1.如果两个对象相同(即equal ...
- 【原创】关于java对象需要重写equals方法,hashcode方法,toString方法 ,compareto()方法的说明
在项目开发中,我们都有这样的经历,就是在新增表时,会相应的增加java类,在java类中都存在常见的几个方法,包括:equals(),hashcode(),toString() ,compareto( ...
- 为什么重写equals必须重写hashCode
目录 equals常见面试题 为什么要重写equals 重写equals不重写hashCode会存在什么问题 总结 equals常见面试题 在开始聊之前,我们先看几个常见的面试题,看看你能不能都回答上 ...
- 为什么重写equals必须重写hoshCode的基础分析
为什么重写equals必须重写hoshCode的基础分析 1.我们先来了解下原生的equals和hashCode代码 原生equals:它判断的是两个对象是否相等 原生hashCode值:它是根据内存 ...
- 为什么要重写equals()方法与hashCode()方法
在java中,所有的对象都是继承于Object类.Ojbect类中有两个方法equals.hashCode,这两个方法都是用来比较两个对象是否相等的. 在未重写equals方法我们是继承了object ...
- Hibernate中为什么要重写equals方法和hashcode方法
1.*为什么要重写equals方法,首先我们来看一下equals源码: public boolean equals(Object anObject) { if (this == anObject) { ...
- JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法
在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...
- JAVA 重写equals和重写hashCode
面试官可能会问你:“你重写过 hashcode 和 equals 么,为什么重写equals时必须重写hashCode方法?” 首先你需要了解: hashCode()的作用是获取哈希码(散列码) 它实 ...
- 为什么重写equals必须重写hashcode?
示例代码: class User { private String name; public User(String name) { this.name = name; } @Override pub ...
随机推荐
- jQuery+JSON+jPlayer实现QQ空间音乐查询
演示地址: http://bejson.com/demos/qqmusic/ 代码下载:http://www.jqdemo.com/932.html 查询QQ音乐是很早前就出来的一个接口. 这里使用j ...
- HDFS中PathFilter类
HDFS中PathFilter类 在单个操作中处理一批文件,这是很常见的需求.比如说处理日志的MapReduce作业可能需要分析一个月内包含在大量目录中的日志文件.在一个表达式中使用通配符在匹配多个文 ...
- 通过jquery来实现文本框和下拉框动态添加效果,能根据自己的需求来自定义最多允许添加数量,实用的jquery动态添加文本框特效
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Hackers’ Crackdown-----UVA11825-----DP+状态压缩
题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- 使用 IDEA 创建 Maven Web 项目 (一)- 使用IEAD创建Maven项目
创建IDEA项目 单击 Create New Project 按钮,弹出 New Project 对话框. 选择 Maven 选项,单击 Next 按钮. 输入 GroupId.ArtifactId. ...
- Web window.print() 打印
web打印 window.print() 我只给出比较有效的,方便的打印方法,有些WEB打印是调用ActiveX控件的,这样就需要用户去修改自己IE浏览器的Internet选项里的安全里的Active ...
- winServer2008添加IIS服务
右键我的电脑,选择管理,打开服务器管理器 点击左边菜单栏角色调出角色窗口 接着点击添加角色,弹出添加角色向导 点击下一步进入服务器角色选项 勾选Web服务器(IIS),点击下一步 出现 点击下一步,出 ...
- mysql 保存emoji时报,数据库报错:Caused by: java.sql.SQLException: Incorrect string value: '\xF0\x9F\x98\x82\xF0\x9F...' for column 'review' at row 1
错误原因:我们可以看到错误提示中的字符0xF0 0x9F 0x98 0x84 ,这对应UTF-8编码格式中的4字节编码(UTF-8编码规范).正常的汉字一般不会超过3个字节,为什么为出现4个字节呢?实 ...
- angularjs-xeditable整合typeahead完成智能提示
按照需求,需要在angularjs的xeditable中加入typeahead,来完成智能提示,并且在选择后,把该条数据的其他信息也显示在此行中,于是做了一下的测试修改. 当然,既然用了xeditab ...
- WebForm 分页与组合查询
1.封装实体类 2.写查询方法 //SubjectData类 public List<Subject> Select(string name) { List<Subject> ...