在Java中,当你重写equals(Object obj)
方法时,通常也建议重写hashCode()
方法,基于Java集合框架中哈希表(如HashMap
、HashSet
等)的工作原理以及hashCode()
和equals()
方法之间的一致性约定。
一致性约定:
Java文档明确指出,如果两个对象通过equals(Object obj)
方法比较是相等的,那么调用这两个对象中任意一个对象的hashCode()
方法必须产生相同的整数结果。这是hashCode()
和equals()
方法之间的一致性约定。
集合框架的依赖:
Java集合框架中的许多类(如HashMap
、HashSet
等)都依赖于hashCode()
和equals()
方法来正确地管理元素。特别是,这些集合使用哈希码来快速定位元素在哈希表中的位置(即“桶”或“槽”)。
为什么需要同时重写:
-
正确性:如果不重写
hashCode()
方法,即使两个对象通过equals()
方法比较是相等的,它们也可能有不同的哈希码。这会导致它们被放置在哈希表的不同位置,从而违反了一致性约定,并可能导致集合操作(如contains
、remove
等)的行为不正确。 -
性能:即使两个对象不相等,但如果它们的哈希码相同(即发生了哈希冲突),它们也会被放置在同一个哈希桶中。此时,
equals()
方法将被用来进一步区分这些对象。如果equals()
方法被正确重写但hashCode()
方法没有,那么即使对象不相等,也可能因为哈希冲突而频繁地调用equals()
方法,从而降低性能。 -
遵守约定:Java平台的设计者期望开发者在重写
equals()
方法时同时考虑hashCode()
方法。这是Java集合框架能够正确工作的基础之一。
示例:
考虑一个Person
类,其中只重写了equals()
方法而没有重写hashCode()
方法。如果两个Person
对象具有相同的name
和age
(因此通过equals()
方法比较是相等的),但由于没有重写hashCode()
方法,它们可能具有不同的哈希码。当这些对象被用作HashSet
或HashMap
的键时,就可能导致集合无法正确地识别它们为相等的对象,从而引发问题。
总结:
equals
方法判断两个对象是相等的,那这两个对象的hashCode
值也要相等。- 两个对象有相同的
hashCode
值,他们也不一定是相等的(哈希碰撞)。