为什么要重写equals()方法与hashCode()方法
在java中,所有的对象都是继承于Object类。Ojbect类中有两个方法equals、hashCode,这两个方法都是用来比较两个对象是否相等的。
在未重写equals方法我们是继承了object的equals方法,那里的 equals是比较两个对象的内存地址,显然我们new了2个对象内存地址肯定不一样
- 对于值对象,==比较的是两个对象的值
- 对于引用对象,比较的是两个对象的地址
Object 默认的equals方法同==,一般来说我们的对象都是引用对象,要重写equals方法。
public boolean equals(Object obj) {
return (this == obj);
}
public static void main(String[] args) {
Object c=new Object();
Object d=new Object();
System.out.println(c.equals(d));//false }
这个比较下,结果是false,也就是这两个对象不一样,但是有些业务,我们需要证明一个类的下面的实例对象时相等的,这时候我们就必须重写equlas方法了。
如下代码,我们新建一个对象Student,并重写equals与hashCode方法
public class Student { private int no; private String name; @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (no != student.no) return false;
return !(name != null ? !name.equals(student.name) : student.name != null); } @Override
public int hashCode() {
int result = no;
result = 31 * result + (name != null ? name.hashCode() : 0);
return result;
} public int getNo() {
return no;
} public void setNo(int no) {
this.no = no;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}
Student a=new Student();
Student b=new Student();
System.out.println(a.equals(b));//ture
此时可以看出a、b对象相等.
hashCode方法也是可以用来比较两个对象是否相等的。但是我们很少使用,应该说是很少直接使用。hashCode方法返回的是一个int值,可以看做是一个对象的唯一编码,如果两个对象的hashCode值相同,我们应该认为这两个对象是同一个对象。
一般如果使用java中的Map对象进行存储时,他会自动调用hashCode方法来比较两个对象是否相等。
所以如果我们对equals方法进行了重写,建议一定要对hashCode方法重写,以保证相同的对象返回相同的hash值,不同的对象返回不同的hash值。
1、重写equals方法时需要重写hashCode方法,主要是针对Map、Set等集合类型的使用;
a: Map、Set等集合类型存放的对象必须是唯一的;
b: 集合类判断两个对象是否相等,是先判断equals是否相等,如果equals返回TRUE,还要再判断HashCode返回值是否ture,只有两者都返回ture,才认为该两个对象是相等的。
2、由于Object的hashCode返回的是对象的hash值,所以即使equals返回TRUE,集合也可能判定两个对象不等,所以必须重写hashCode方法,以保证当equals返回TRUE时,hashCode也返回Ture,这样才能使得集合中存放的对象唯一。
个人感觉equals重写,是站在使用的角度上考虑的:类设计者不希望通过内存地址来比较两个对象是否相等,重写这个equals方法,能够方便的使用Collection<E>操作自定义对象E(Collection中很多方法涉及E.equals()的);而hashCode的重新,是方便Map<K,V>的使用,良好的自定义hashCode,会极大的提高Map的使用效率。 为啥说equals重新时,一定要重写hashCode?感觉这么理解不知行不行:既然自定义类重写了equals方法,说明类设计者不希望通过内存地址来比较两个对象是否相等了。而Object的hashCode也是对象的内存地址,既然不希望通过地址比较对象,那么以内存地址作为hashCode也就没有实际使用意义了,索性将自定义对象的hashCode方法也重写了吧!
参考: hashCode的作用 重写equals方法为什么要重写hashCode方法
为什么要重写equals()方法与hashCode()方法的更多相关文章
- JAVA正确地自定义比较对象---如何重写equals方法和hashCode方法
在实际应用中经常会比较两个对象是否相等,比如下面的Address类,它有两个属性:String province 和 String city. public class Address { priva ...
- HashSet中存方用户自己定义数据类型数据,重写equals方法和hashCode方法
import java.util.Set; import java.util.HashSet; public class SetTest { public static void main(Strin ...
- Hibernate中为什么要重写equals方法和hashcode方法
1.*为什么要重写equals方法,首先我们来看一下equals源码: public boolean equals(Object anObject) { if (this == anObject) { ...
- 对象作为 map 的 key 时,需要重写 equals 方法和 hashCode 方法
对象作为 map 的 key 时,需要重写 hashCode 和 equals方法 如果没有重写 hashCode 方法,那么下面的代码示例会输出 null 我们首先定义一个对象:BmapPoint, ...
- Java重写equals方法和hashCode方法
package com.ddy; public class User { private Integer id; private String name; private St ...
- HashSet中的元素必须重写equals方法和hashCode方法
http://jingyan.baidu.com/article/d5a880eb8fb61d13f147cc99.html 1.为什么必须重写这两个方法. 2.什么事hashSet去重,符合什么样的 ...
- JAVA中equals方法与hashCode方法学习
首先参考文章:http://www.oschina.net/translate/working-with-hashcode-and-equals-methods-in-java 1,equals方法的 ...
- 关于Object类的equals方法和hashCode方法
关于Object类的equals的特点,对于非空引用: 1.自反性:x.equals(x) return true : 2.对称性:x.equals(y)为true,那么y.equals(x)也为tr ...
- java中equals方法和hashcode方法的区别和联系,以及为什么要重写这两个方法,不重写会怎样
一.在Object类中的定义为:public native int hashCode();是一个本地方法,返回的对象的地址值.但是,同样的思路,在String等封装类中对此方法进行了重写.方法调用得到 ...
- Java 如何重写对象的 equals 方法和 hashCode 方法
前言:Java 对象如果要比较是否相等,则需要重写 equals 方法,同时重写 hashCode 方法,而且 hashCode 方法里面使用质数 31.接下来看看各种为什么. 一.需求: 对比两个对 ...
随机推荐
- Ext.Net学习笔记21:Ext.Net FormPanel 字段验证(validation)
Ext.Net学习笔记21:Ext.Net FormPanel 字段验证(validation) 作为表单,字段验证当然是不能少的,今天我们来一起看看Ext.Net FormPanel的字段验证功能. ...
- 杂技之sharpdevelop调试aps.net
背景: 本人笔记本电脑不给力,vs打开实在太慢,因此考虑使用sharpdevelop,但sharpdevelop有点麻烦事,就是不支持asp.net的调试,为解决此问题,本人在此杂技一把了 方案一: ...
- ios - objective-c runtime之随笔
今天身体不舒服,还顶着写这篇博客. 举个例子,我们之前在写objective-c代码时,经常用到id这个关键字.那 id 究竟是什么?在objective-c的运行时,这样描述的,它其实是一个结构体( ...
- java集合框架示例图
- 几个app maker的网站
简网APP工场:http://www.cutt.com/app 爱传iappk:http://www.iappk.com 安米网:http://www.appbyme.com/mobcentACA/i ...
- SVN查看提交日志的命令
Windows下,使用svn客户端查看日志很方便,但是如果在linux下,常规查看日志的命令对于日志记录数比较多的时候,屏幕显示不了,就比较麻烦,后来发现了一个很有用的参数可以限制要查看的记录条数 查 ...
- ubuntu12.10可用更新源
ubutnu12.10自带的更新源已经失效,国内各大服务器的更新源,无论是网易.搜狐还是教育网的因此也失效了.附件是ubuntu12.10目前的可用更新源. 将地址中的“us.archive”换成“o ...
- wifidog编译到openwrt
首先敲一下 cd 命令,定位到自己的用户目录, 然后 mkdir openwrt 新建一个openwrt文件夹,然后开始装openwrt的编译用到的工具, sudo apt-get install g ...
- 解决Ubuntu和Windows的文件乱码问题(转载)
解决Ubuntu和Windows的文件乱码问题(debian也通用) 1.转换文件内容编码 Windows下天生的纯文本文件,其中文编码为GBK,在Ubuntu下显示为乱码,可以使用iconv命令 ...
- Python3 IO
在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中 ...