Java中hashCode和equals方法的比较

日期: 2019-06-13

  一、equals

  首先我们要明白equals和hashcode方法都是从object类中继承过来的。

  equals()方法在object类中定义如下:

  public boolean equals(Object obj) {

  return (this == obj);

  }

  很明显是对两个对象的地址值进行的比较(即比较引用是否相同)。但是我们必需清楚,String 、Integer、Double等这些封装类在使用equals()方法时,已经覆盖了object类的equals()方法。

  public boolean equals(Object anObject) {

  if (this == anObject) {

  return true;

  }

  if (anObject instanceof String) {

  String anotherString = (String)anObject;

  int n = count;

  if (n == anotherString.count) {

  char v1[] = value;

  char v2[] = anotherString.value;

  int i = offset;

  int j = anotherString.offset;

  while (n-- != 0) {

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

  return false;

  } return true;

  }

  } return false;

  }

  很明显,这是进行的内容比较,而已经不再是地址的比较,这也是我们程序设计者想要的。

  二、hasdcode

  其实是hasdCode方法,在object类中定义如下:

  public native int hashCode();

  说明是一个本地方法,它的实现是根据本地机器相关的。当然我们可以在自己写的类中覆盖hashcode()方法,比如String、Integer、Double等等这些类都是覆盖了hashcode()方法的。

  例如在String类中定义的hashcode()方法如下:

  public int hashCode() {

  int h = hash;

  if (h == 0) {

  int off = offset;

  char val[] = value;

  int len = count;

  for (int i = 0; i < len; i++) {

  h = 31*h + val[off++];

  }

  hash = h;

  }

  return h;

  }

  三、equals和hashcode方法的区别

  这里我们首先要明白一个问题:

  equals()相等的两个对象,hashcode()一定相等;equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。换句话说,equals()方法不相等的两个对象,hashcode()有可能相等。(我的理解是由于哈希码在生成的时候产生冲突造成的)。 反过来:hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。

  四、总结

  在java的集合中,判断两个对象是否相等的规则是:

  1、判断两个对象的hashCode是否相等

  ①如果不相等,认为两个对象也不相等,完毕

  ②如果相等,转入2

  (这一点只是为了提高存储效率而要求的,其实理论上没有也可以,但如果没有,实际使用时效率会大大降低,所以我们这里将其做为必需的。后面会重点讲到这个问题。)

  2、判断两个对象用equals运算是否相等

  ①如果不相等,认为两个对象也不相等

  ②如果相等,认为两个对象相等(equals()是判断两个对象是否相等的关键)

  为什么是两条准则,难道用第一条不行吗?不行,因为前面已经说了,hashcode()相等时,equals()方法也可能不等,所以必须用第2条准则进行限制,才能保证加入的为非重复元素。