首先,我们应该知道对象放入散列集合的时候,先进行hashCode值的比较,然后进行equals的比较,此时在重写equals()方法的同时,必须重写hashCode()方法。在Java中任何一个对象都具备equals(Object obj)和hashCode()这两个方法。
二者关系:
两个对象 equals的时候,hashCode必须相等,但hashCode相等,对象不一定equals。 如果没有重写 hashcode方法,使用Object自带的hashCode,无法保证两个对象equals的时候 hashCode 必须相等的条件。
1.hashCode:hashCode()方法返回一个int数,在Object类中的默认实现是“将该对象的内部地址转换成一个整数返回”。
JDK17中对hashCode的协议:
- 在Java应用程序执行期间,只要在同一对象上多次调用该方法,该
hashCode
方法必须始终返回相同的整数,前提equals
是没有修改对象比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。 - 如果根据方法两个对象相等
equals
,则对两个对象中的每一个调用该hashCode
方法必须产生相同的整数结果。 - 不要求如果两个对象根据方法不相等,
equals
则对两个对象中的每一个调用该hashCode
方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
2.equals: equals(Object obj)方法用来判断两个对象是否“相同”,如果“相同”则返回true,否则返回false。
JDK17中对equals 方法在非空对象引用上实现相等关系 :
- 自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
- 对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
- 传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
- 一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
- 对于任何非空引用值 x,x.equals(null) 都应返回 false。
注:
1.hashCode()方法存在的主要目的就是提高效率。
2.在集合中判断两个对象相等的条件,其实无论是往集合中存数据,还是从集合中取数据,包括如何控制唯一性等,都是用这个条件判断的,条件如下:首先判断两个对象的hashCode是否相等,如果不相等,就认为这两个对象不相等,就完成了。如果相等,才会判断两个对象的equals()是否相等,如果不相等,就认为这两个对象不相等,如果相等,那就认为这两个对象相等。