• 为什么要重写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;都会出现什么情况

  • 相关阅读:
    hdu 1199 Color the Ball 离散线段树
    poj 2623 Sequence Median 堆的灵活运用
    hdu 2251 Dungeon Master bfs
    HDU 1166 敌兵布阵 线段树
    UVALive 4426 Blast the Enemy! 计算几何求重心
    UVALive 4425 Another Brick in the Wall 暴力
    UVALive 4423 String LD 暴力
    UVALive 4872 Underground Cables 最小生成树
    UVALive 4870 Roller Coaster 01背包
    UVALive 4869 Profits DP
  • 原文地址:https://www.cnblogs.com/tinaluo/p/8329197.html
Copyright © 2020-2023  润新知