JAVA重写equals方法

    技术2022-05-14  2

    VA问题的引出:今天编写贪吃蛇程序的时候遇到这样一个问题

    public class Coordinate {

     public int headX, headY;

     Coordinate(int headX, int headY) {   this.headX = headX;   this.headY = headY;  }     public boolean equals(Coordinate c) {

       if(this.headX == c.headX && this.headY == c.headY) {

          return true;    } else {

          return false;

       } }

    说明:Coordinate 是一个坐标类,重写equals方法的原因是要比较蛇身是否到达了记录下来的蛇头的转弯点,于是自己重写了equals方法,但是发现没有效果,即使x,y的值一样,返回的也是false。

    为了进一步熟悉equals方法,于是自己又先写了下面一个验证的程序:

    public class TestEquals {  public static void main(String[] args) {   Dog d1 = new Dog(1);   Dog d2 = new Dog(1);   System.out.println(d1 == d2);

      System.out.println(d1.equals(d2));  } }

    class Dog {  int weight;    Dog(int weight) {   this.weight = weight;  }

     

      public boolean equals(Dog d) {

        if(this.weight == d.weight) {

           return true;

        } else {

           return false;

        }

      } }

    当然结果是一样的,为了进一步验证,于是就进一步重写了hashCode()方法:

    public int hashCode() {

       return 0;

    }

    因为有时候优先比较的是hashCode码。但是结果还是不行。我只好找回原来看过的马士兵老师的视频教程,才发现自己对这个重写很不熟悉,正确的写法应该是:

    public class Coordinate {

     public int headX, headY;

     Coordinate(int headX, int headY) {   this.headX = headX;   this.headY = headY;  }    public int hashCode() {   return 0;  }    public boolean equals(Object obj) {   if(obj == null) {    return false;   } else {    if(obj instanceof Coordinate) {     Coordinate coo = (Coordinate)obj;     if(this.headX == coo.headX && this.headY == coo.headY) {      return true;     } else {      return false;     }    }   }   return false;  } }

    因为其传递的是Object类型,因此首先必要的是判断他是否为空,然后再判断他是不是自己要的类型:

    obj instanceof Coordinate;

    如果是则还要首先将其强制转换成自己要的类型。

    Coordinate coo = (Coordinate)obj;

    接着再进行判断,这样一来程序就正确了。

    。。。。。。

    剩下就是那个hashCode方法的重写了,这里没有重写hashCode()方法也是行的,所以不太清楚到底什么时候要重写该方法。尚有待考究。。。。。。

    下面是网上某个博客找到的资料:

    equals方法是Object的重要方法。重写遵循一下原则:

    1.自反性,对于任何引用,只要不为null,那么对其自身使用equals方法永远放回true; 2.对称性,对于任何引用a,b.如果都不为nul,则a.equals(b)≡b.equals(a); 3.传递性,对于任何非空引用a,b,c,如果a.equals(b)==true,b.equals(c)==true,则a.equals(c)==true; 4.一致性,对于任何非空引用a,b,在参与equals比较的成员没有被修改的情况下,多次对a和b进行equals比较,结果应该始终相同; 5,任何非空引用a,a.equals(null)≡false; 通过一上几条规定可以得出重写equals方法有有一下几个步骤需要完成: 1,应该首先测试两个引用是否指向同一个对象.是则返回true,这一步可以提高效率; 2,接下来测试传进来的对象是否为空,是则返回false; 3,测试传进来的对象是否通过自己的instanceof,不通过则返回false; 4,将传进来的对象强制转换成自己的类型,对相关成员进行比较. 特别注意: 1.方法修饰符必须是public,因为是重写的Object的方法. 2.参数类型必须是Object. 3.重写了equals必须重写hashcode方法.否则两个等价对象可能得到不同的hashcode,这在集合框架中使用可能产生严重后果. 重写hashcode方法: 1.java程序运行期间,于同一对象多次调用hashcode方法时,在对象上参与equals比较的成员没有被修改的情况下,必须返回一直的整数. 2.从某一程序的执行到同一程序的另外一次执行,该整数无需保持一致. 3.如果两个对象各自调用hashcode方法返回的值不一致,那么这两个对象进行equals一定返回false. 4.如果equals方法返回true,则hashcode方法必须返回相同的值. 5.如果equals返回false,则hashcode比一定返回不同值. *hashcode主要是用来提高hash系统的查询效率. a.equals(b)==true必须a.hashcode()==b.hashcode(); a.hashcode!=b.hashcode则a.equals(b)==false;

    最新回复(0)