zoukankan      html  css  js  c++  java
  • 为什么要重写hashCode()方法和equals()方法及如何重写

    我想写的问题有三个:

    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);

    }

    }

    结果:true

    145

    145

    [3,4 , 6,4 , 10,7 ,8,9 ]

    可以自己试一下,hashCode()返回值相等,equals()返回false;和hashCode()返回值不相等,equals()返回值为true;都会出现什么情况

  • 相关阅读:
    Struts2_day01--导入源文件_Struts2的执行过程_查看源代码
    R语言低级绘图函数-text
    R语言低级绘图函数-rect
    R语言低级绘图函数-arrows
    R语言低级绘图函数-abline
    R语言绘图布局
    find_circ 识别circRNA 的原理
    CIRI 识别circRNA的原理
    circRNA 序列提取中的难点
    tRNA 二级结构预测可视化
  • 原文地址:https://www.cnblogs.com/tinaluo/p/8329197.html
Copyright © 2011-2022 走看看