为什么要重写equals方法和hashcode方法

时间:2021-08-05 16:01:51

1.equals方法来自Object类,Object类中的equals方法比较两个引用类型的对象时,只有两个对象的地址相同时,才返回true。所以如果是自定义的类型,要比较两个对象是否相等,可以有自己的规则,比如某些属性相等就返回true。

2.

hashcode()这个方法也是从object类中继承过来的,在object类中定义如下: 

       public native int hashCode(); 

      说明是一个本地方法,它的实现是根据本地机器相关的。再看它比较“官方”的详细说明:hashCode()返回该对象的哈希码值,该值通常是一个由该对象的内部地址转换而来的整数,它的实现主要是为了提高哈希表(例如java.util.Hashtable提供的哈希表)的性能。

      你可以对它的这样“官方式”的定义漠视,但以下这一点你必须铭记:在每个重写了equals方法的类中,你必须也要重写hashCode方法。如果不这样做的话,就会违反Object.hashCode的通用约定,从而导致该类无法与所有基于散列值(hash)的集合类结合在一起正常运行。 

      hashCode()的返回值和equals()的关系如下:

      如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。 

      如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

***正确书写hashCode的办法:

【原则】按照equals( )比较两个对象是否一致条件用到的属性重写hashCode()

{1}. 常用的办法就是利用涉及到的的属性进行线性组合

{2}. 线性组合过程中涉及到的组合系数自定义即可。

注意,拼接之后的数值不能超过整形的表达范围。

{3}. 公式:属性1的int形式+ C1*属性2的int形式+  C2*属性3的int形式+ …

【技巧】当属性是引用类型的时候,如果已经重写过hashCode(),那么这个引用属性的int形式就是直接调用属性已有的hashCode值。

最典型的就是这个属性是字符串类型的,String类型已经重写了hashCode()方法,所以直接拿来使用即可。

如:public class Person{

  private String name;

  private int age;

  public Person(){}

  public Person(String name, int age){

    this.name = name;

    this.age = age;

  }

  //get set方法

  public void setName(String name){

    ......

  }

  。。。

}

  //重写hashcode方法

  

public int hashCode(){

    sop(this.name +"......hashCode");

    return this.name.hashCode() + 29*age;

}

另外参看:http://blog.csdn.net/benjaminzhang666/article/details/9468605