JVM是从内存角度看对象的,内存一样的对象才算是相等的,所以,内存的唯一性决定了对象只能是“自己和自己才是相等的”。
Java的“==”规则是个内存判断,默认的equals()也使用了“==”规则:
/**
* 该方法应该满足五个条件:
* 1、自反性:任意对象x,x.equals(x)==true
* 2、对称性:任意对象x、y,如果x.equals(y)==true,那么,y.equals(x)==true
* 3、传递性:任意对象x、y、z,如果x.equals(y)==true,并且y.equals(z)==true,那么,x.equals(z)==true
* 4、一致性:任意对象x、y,如果对象中用于等价比较的信息没有改变,那么x.equals(y)返回的结果应该始终一致,要么true,要么false
* 5、任何不是null的x,x.equals(null)一定返回false
*/
public boolean equals(Object obj) {
return (this == obj);
}
hashcode()方法是计算对象的散列码,在散列数据结构当中用来定位对象的位置。常用的HashMap就是个散列结构。
每个对象都有一个散列码,在对象刚刚被创建的时候就生成好了,以后都不会再发生变化,不同对象的散列码可能会相同,这就是散列冲突问题。
基于内存视角的JVM规则,可以保证:在散列数据结构当中,相等的对象可以被散列到相同的位置,因为对象只能和自己相等!
如果我们重写了equals()方法,就相当于改变了JVM默认的内存视角规则,开始从我们的业务视角去看待对象相等的问题了。这样就会导致了一个现象:不同内存的两个对象A和B,可以是相等的!这与JVM默认的内存规则是相违背的。
如果我们不去重写hashcode(),使用JVM默认规则可以预见:A和B两个对象的散列码是不一样的(有可能一样,概率很低)。
这就会出现一个很严重的问题:在散列数据结构当中,相等的对象被散列到了不同的位置(有可能相同,概率很低)!
散列数据结构的理论遭到了严重破坏!后果就是使用HashMap这些基于散列结构的类会出错,导致不可预知的错误结果,程序就不可能正确执行。
所以,改变了equals()规则,就需要改变hashcode()规则,这也是重写hashcode()方法的意义所在,保证散列数据结构理论的正确性:相等对象可以被散列到相同的位置!