关于equals与hashcode的重写
我想写的问题有三个:
1、首先我们为什么需要重写hashCode()方法和equals()方法
2、在什么情况下需要重写hashCode()方法和equals()方法
3、如何重写这两个方法
*********************************************************************
第一个问题:为什么需要重写hashCode()方法和equals()方法
Java中的超类Object类中定义的equals()方法是用来比较两个引用所指向的对象的内存地址是否一致
Object类中equals()方法的源码
public boolean equals(Object obj) {
return (this == obj);
}
********************************************************************
Object类中的hashCode()方法,用native关键字修饰,说明这个方法是个原生函数,也就说这个方法的实现不是用java语言实现的,是使用c/c++实现的,并且被编译成了DLL,由java去调用,jdk源码中不包含。对于不同的平台它们是不同的,java在不同的操作系统中调用不同的native方法实现对操作系统的访问,因为java语言不能直接访问操作系统底层,因为它没有指针。
这种方法调用的过程:
1、在java中申明native方法,然后编译
2、用javah产生一个 .h 文件
3、写一个 .cpp文件实现native导出方法,其中需要包含第二步产生的.h文件(其中又包含了jdk带的jni.h文件);
4、将.cpp文件编译成动态链接库文件
5、在java中用System.loadLibrary()文件加载第四步产生的动态链接库文件,然后这个navite方法就可被访问了
Java的API文档对hashCode()方法做了详细的说明,这也是我们重写hashCode()方法时的原则【Object类】
重点要注意的是:
a. 在java应用程序运行时,无论何时多次调用同一个对象时的hsahCode()方法,这个对象的hashCode()方法的返回值必须是相同的一个int值
b. 如果两个对象equals()返回值为true,则他们的hashCode()也必须返回相同的int值
c. 如果两个对象equals()返回值为false,则他们的hashCode()返回值也必须不同
public native int hashCode();
现在到了说正题了,为什么要重写
我们在定义类时,我们经常会希望两个不同对象的某些属性值相同时就认为他们相同,所以我们要重写equals()方法,按照原则,我们重写了equals()方法,也要重写hashCode()方法,要保证上面所述的b,c原则;所以java中的很多类都重写了这两个方法,例如String类,包装类
4、第二个问题:在什么情况下需要重写hashCode()方法和equals()方法
当我们自定义的一个类,想要把它的实例保存在集合中时,我们就需要重写这两个方法;集合(Collection)有两个类,一个是List,一个是Set
List:集合中的元素是有序的,可以重复的
Set:无序,不可重复的
以HashSet来说明:
HashSet存放元素时,根据元素的hashCode值快速找到要存储的位置,如果这个位置有元素,两个对象通过equals()比较,如果返回值为true,则不放入;如果返回值为false,则这个时候会以链表的形式在同一个位置上存放两个元素,这会使得HashSet的性能降低,因为不能快速定位了。还有一种情况就是两个对象的hashCode()返回值不同,但是equals()返回true,这个时候HashSet会把这两个对象都存进去,这就和Set集合不重复的规则相悖了;所以,我们重写了equals()方法时,要按照b,c规则重写hashCode()方法!
5、第三个问题:如何重写这两个方法
我写了一个例子,大家可以看一下
*******************************************************************************
package cn.hashCode.jing;
/**
*定义一个Ponint测试类,用来测试Set集合保存元素的方式中
*hashCode()方法和equals()方法对Set集合保存元素影响
*
*/
public final class Point {
private int x;
private int y;
public Point(){
super();
}
public Point(int x,int y){
this.x=x;
this.y=y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(obj!=null && obj.getClass()==Point.class){
Pointpo=(Point)obj;
if(this.x==po.x && this.y==po.y){
return true;
}
}
return false;
}
@Override
public int hashCode(){
return 7*x+31*y;
}
/*以下是自动生成的
@Override
publicboolean equals(Object obj) {
if(this == obj)
returntrue;
if(obj == null)
returnfalse;
if(getClass() != obj.getClass())
returnfalse;
Pointother = (Point) obj;
if(x != other.x)
returnfalse;
if(y != other.y)
returnfalse;
returntrue;
}
@Override
publicint hashCode() {
finalint prime = 31;
intresult = 1;
result= prime * result + x;
result= prime * result + y;
returnresult;
}*/
public String toString(){
return x+","+y+" ";
}
}
package cn.hashCode.jing;
import java.util.HashSet;
public class TestHashSet {
public static void main(String[] args) {
HashSet<Point>hs=new HashSet<Point>();
Pointp1=new Point(3,4);
Pointp2=new Point(6,4);
Pointp3=new Point(10,7);
Pointp4=new Point(8,9);
Pointp5=new Point(3,4);
hs.add(p1);
hs.add(p2);
hs.add(p3);
hs.add(p4);
hs.add(p5);
System.out.println(p1.equals(p5));
System.out.println(p1.hashCode());
System.out.println(p5.hashCode());
System.out.println(hs);
}
}
关于equals与hashcode的重写的更多相关文章
- 关于HashSet的equals和hashcode的重写
关于HashSet的equals和hashcode的重写:package Test; import java.util.HashSet; import java.util.Set; public cl ...
- Java--equals和 == 的比较和equals()、HashCode()的重写
一. equals和 == 的比较 1.== 运算符 ① == 如果比较的是基本数据类型,则比较的是值. ② == 如果比较的是引用数据类型,则比较的是地址值. 2.equals ①它属于java.l ...
- java中equals与hashCode的重写问题
这几天有一个朋友问我在重写equals和hashCode上出现了问题,最后我帮她解决了问题,同时也整理出来分享给大家 现上Object的equals与HashCode的代码 public boolea ...
- Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)
Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例 原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...
- 【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例
原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例 部分代码参考http ...
- 重写equals()与hashCode()方法
出自:http://blog.csdn.net/renfufei/article/details/16339351 Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类.Oj ...
- 为什么要重写equals和hashCode
1.重写equals方法时需要重写hashCode方法,主要是针对Map.Set等集合类型的使用: a: Map.Set等集合类型存放的对象必须是唯一的: b: 集合类判断两个对象是否相等,是先判断e ...
- 为什么要重写equals和hashcode方法
equals hashcode 当新建一个java类时,需要重写equals和hashcode方法,大家都知道!但是,为什么要重写呢? 需要保证对象调用equals方法为true时,hashcode ...
- Java中equals()和hashCode()的关系以及重写equals()和hashCode()的重要性
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6580647.html 一:关系 如果两个对象相等(equal),它们的hashcode一定相同: 如果两个对 ...
随机推荐
- TCP/IP协议的学习笔记
1.OSI和TCP/IP的协议体系结构 OSI是开放系统互连参考模型,它的七层体系结构概念清楚,理论也比较完整,但它既复杂又不实用.而TCP/IP是一个四层的体系结构,它包含应用层.传输层.网际层和网 ...
- JAVA基础学习之路(四)定义简单java类
简单java类开发一般原则: 类名称必须有意义,再怎么说,要让人家看的明白吧 类之中所有属性必须使用private封装,并提供setter,getter方法 类之中可以有多个构造方法,但是必须保留有一 ...
- python程序设计——面向对象程序设计:类
理解面向对象 基本原则是,计算机程序由多个能够起到子程序作用的单元或对象组合而成 关键性观念是,数据以及对数据的操作封装在一起,组成一个相互依存.不可分割的整体,即对象 python面向对象特性 完全 ...
- win7下本地运行spark以及spark.sql.warehouse.dir设置
SparkSession spark = SparkSession .builder() .master("local[*]") .enableHiveSupport() .con ...
- python作业:三级菜单(第一周)
一.作业需求: 1. 运行程序输出第一级菜单 2. 选择一级菜单某项,输出二级菜单,同理输出三级菜单 3. 菜单数据保存在文件中 4. 让用户选择是否要退出 5. 有返回上一级菜单的功能 二.三级菜单 ...
- Linux中常用的关机和重新启动命令
hutdown.halt.reboot以及init,它们都可以达到关机和重新启动的目的,但是每个命令的内部工作过程是不同的,下面将逐一进行介绍. 一.shutdown shutdown命令用于安全关闭 ...
- css重修之书(一):如何用css制作比1px更细的边框
如何用css制作比1px更细的边框 在项目的开发过程中,我们常常会使用到border:1px solid xxx,来对元素添加边框: 可是1px的border看起来还是粗了一些粗,不美观,那么有什么方 ...
- jQuery实现仿京东商城图片放大镜
效果图: 不废话直接上代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- 个人在git配置SSH Key遇到的问题以及解决方案
第一次用git上传代码到github,在这过程中遇到很多问题,在输入git命令的时候都小心翼翼,因为一不小心感觉就会出错.. 英语不好..在敲入git命令过程中各种错误提示勉强翻译下才看得懂 最后输入 ...
- A4
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 很胖,刚学,照猫画虎做了登录与注册界面. 展示GitHub ...