疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

Java中equals与hashCode的重写问题


 

   

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

  现上Object的equals与HashCode的代码

  public boolean equals(Object obj) {

  return (this == obj);

  }

  public native int hashCode();

  由上面可以看到Object的equlas方法等价于“==”,所以不能满足我们平时的需求,因此我们需要重写equals,在java中我们约定了重写equals的时候也要重写HashCode方法,可以参考String的equals与HashCode的方法,ok。。。上代码

  复制代码

  public boolean equals(Object anObject) {

  if (this == anObject) {

  return true;

  }

  if (anObject instanceof String) {

  String anotherString = (String) anObject;

  int n = value.length;

  if (n == anotherString.value.length) {

  char v1[] = value;

  char v2[] = anotherString.value;

  int i = 0;

  while (n-- != 0) {

  if (v1[i] != v2[i])

  return false;

  i++;

  }

  return true;

  }

  }

  return false;

  }

  复制代码

  复制代码

  public int hashCode() {

  int h = hash;

  if (h == 0 && value.length > 0) {

  char val[] = value;

  for (int i = 0; i < value.length; i++) {

  h = 31 * h + val[i];

  }

  hash = h;

  }

  return h;

  }

  复制代码

  现在说说我对这两个方法的个人理解心得

  我们可以把HashCode理解为词典中的索引比如“词语”,“词典”两个词,所以当HashCode相同时,equals不一定相同,反过来equals相同。HashCode就一定相等,总结就是 equals相等,hashcode一定相等,equals不相等,hashcode不一定不相等(个人理解可能在某些问题上会有局限性)

  下面是是我自己重写的一个equals与HashCode的方法,具体问题都标注在代码中了

  复制代码

  public class Dog {

  public String name;

  public int age;

  public Dog(String name,int age){

  this.name=name;

  this.age=age;

  }

  @Override

  public boolean equals(Object obj) {

  if(this==obj) return true;

  /*第一个是通过比较地址来间接比较值的,毋庸置疑,如果地址是一样的话,那么值也是一样的。还有一点也能说明为什么是比较值而不是地址,

  那就是第一个判断只有返回true而没有返回false。因为如果是false的话那么说明地址是不同的,但是地址不同并不能说值不同,所以没

  有写返回false也说明了第一个是通过比较地址来间接比较值的,而不是只是简单的比较地址。*/

  if(this==null||(this.getClass()!=obj.getClass())) return false;

  /*if(!(obj instanceof Cat)) return false; 我在网上看到一些人这样写,这样写是不对的,当本类没有子类的时候可以,但是当本类

  存在子类会导致一些问题,======>>  a.equls(b) 返回true b.equals(a) 返回false*/

  Dog dog=(Dog) obj;

  return this.age==dog.age&&this.name.equals(dog.name);

  }

  @Override

  public int hashCode() {

  return name.hashCode()*37+age;

  }

  public static void main(String[] args) {

  HashMap map=new HashMap();

  Dog d1=new Dog("x",1);

  Dog d2=new Dog("x",1);

  map.put(d1, 1);

  System.out.println(d1.equals(d2)); //=====>返回true

  System.out.println(map.get(new Dog("x",1)));  //=====>这里当补充些HashCode的时候的结果是null;只有在重写了HashCode才会出现结果"1"

  }

  }

  复制代码