我想写的问题有三个:

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的重写的更多相关文章

  1. 关于HashSet的equals和hashcode的重写

    关于HashSet的equals和hashcode的重写:package Test; import java.util.HashSet; import java.util.Set; public cl ...

  2. Java--equals和 == 的比较和equals()、HashCode()的重写

    一. equals和 == 的比较 1.== 运算符 ① == 如果比较的是基本数据类型,则比较的是值. ② == 如果比较的是引用数据类型,则比较的是地址值. 2.equals ①它属于java.l ...

  3. java中equals与hashCode的重写问题

    这几天有一个朋友问我在重写equals和hashCode上出现了问题,最后我帮她解决了问题,同时也整理出来分享给大家 现上Object的equals与HashCode的代码 public boolea ...

  4. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

  5. 【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

    原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例   部分代码参考http ...

  6. 重写equals()与hashCode()方法

    出自:http://blog.csdn.net/renfufei/article/details/16339351 Java语言是完全面向对象的,在java中,所有的对象都是继承于Object类.Oj ...

  7. 为什么要重写equals和hashCode

    1.重写equals方法时需要重写hashCode方法,主要是针对Map.Set等集合类型的使用: a: Map.Set等集合类型存放的对象必须是唯一的: b: 集合类判断两个对象是否相等,是先判断e ...

  8. 为什么要重写equals和hashcode方法

    equals hashcode  当新建一个java类时,需要重写equals和hashcode方法,大家都知道!但是,为什么要重写呢? 需要保证对象调用equals方法为true时,hashcode ...

  9. Java中equals()和hashCode()的关系以及重写equals()和hashCode()的重要性

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6580647.html  一:关系 如果两个对象相等(equal),它们的hashcode一定相同: 如果两个对 ...

随机推荐

  1. Aizu - 2249

    注意先保证距离最短,再来判断价格 邻接矩阵回朝内存  ,要用邻接表的 #include<bits/stdc++.h> using namespace std; #define inf 0x ...

  2. Docker Remote API v1.24

    1. Brief introduction The Remote API has replaced rcli. The daemon listens on unix:///var/run/docker ...

  3. mweb test

    目录 Markdown syntax guide and writing on MWeb Philosophy Notice Headers This is an <h1> tag Thi ...

  4. leetcode个人题解——two sum

    这是leetcode第一题,通过较为简单. 第一题用来测试的,用的c,直接暴力法过, /** * Note: The returned array must be malloced, assume c ...

  5. Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点

    Hyperledger fablic 1.0 在centos7环境下的安装与部署和动态增加节点 一.安装docker 执行代码如下: curl -sSL https://get.daocloud.io ...

  6. NMAP-主机扫描

    1.全面扫描 2.扫描指定段 3.ping扫描 只进行ping操作,十分隐蔽 4.无ping扫描 适用于防火墙禁止ping 5.TCP SYN扫描 6.TCP ACK扫描 7.UDP扫描 8.ICMP ...

  7. Scala可变对象

    Java提供JavaBean作为数据对象的封装, 而对于Scala来说也提供了同样的支持. class Apple { var weight: Float = _ var color: String ...

  8. 20145214 《Java程序设计》第6周学习总结

    20145214 <Java程序设计>第6周学习总结 教材学习内容总结 串流设计 Java将输入/输出抽象化为串流,数据有来源及目的地,衔接两者的是串流对象. 输入串流代表对象为java. ...

  9. Ubuntu 配置 Android 开发 环境

    . 果断换Ubuntu了, Ubuntu的截图效果不好, 不能设置阴影 ... 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article ...

  10. Android中的回调Callback

    回调就是外部设置一个方法给一个对象, 这个对象可以执行外部设置的方法, 通常这个方法是定义在接口中的抽象方法, 外部设置的时候直接设置这个接口对象即可. 例如给安卓添加按钮点击事件, 我们创建了OnC ...