为什么覆盖 equals() 一定要覆盖 hashCode()
时间: 2023-02-12 11:36:19 浏览: 58
因为 `equals()` 和 `hashCode()` 方法是相互关联的。当一个类重写了 `equals()` 方法时,通常也需要重写 `hashCode()` 方法,以维护一致性。如果两个对象相等,那么它们的 `hashCode()` 方法应该返回相同的值。因此,在重写 `equals()` 方法后不重写 `hashCode()` 方法,可能导致错误。
相关问题
为什么重写equals还要
### 回答1:
重写 `equals` 是为了比较对象的内容是否相同,而不是比较它们在内存中的地址是否相同。如果没有重写 `equals`,默认情况下会比较对象的引用,即判断两个对象是否指向同一个内存地址,这并不总是我们想要的。
在Java中,如果两个对象的内容相同,我们希望它们被视为相等的,即使它们在内存中的地址不同。因此,我们需要重写 `equals` 方法,自定义比较的逻辑,以满足我们的需求。
### 回答2:
重写equals方法是为了确保对象之间的相等性判断能够符合我们的需求。在默认情况下,equals方法是比较两个对象的引用是否相等,即判断两个对象是否指向同一个内存地址。然而,在实际开发中,我们往往需要根据对象的属性来判断它们是否“相等”,而不仅仅是引用的比较。
重写equals方法的目的是在对象之间进行逻辑上的相等判断。具体来说,通过在类中定义equals方法,可以根据我们自己的定义来比较两个对象的属性是否相等。这样创建的对象,即使是不同的引用,只要属性相同,equals方法将会返回true。
重写equals方法也是为了保证hashCode方法的正确性。根据规范,两个对象如果使用equals方法相等,那么它们的hashCode方法必须返回相同的值。hashCode方法是用来确定对象在散列表中的位置,如果hashCode不一致,会导致对象无法正确存取。
在重写equals方法时,通常需要覆盖一些基本准则,如自反性(x.equals(x)应返回true)、对称性(x.equals(y)与y.equals(x)的结果应该相同)、传递性(x.equals(y)和y.equals(z)为true,那么x.equals(z)也应为true)、一致性(在对象没有被修改的情况下,多次调用equals方法应该返回相同的结果)、非空性(x.equals(null)应返回false)等等。
总之,重写equals方法是为了实现自定义的相等判断,使对象在逻辑上能够符合我们的需求,并保证hashCode方法的一致性,从而能够正确地在集合类等容器中进行操作。
### 回答3:
重写equals方法是为了实现自定义的相等比较规则。
在Java中,Object类的equals方法是用于比较对象的相等性的,默认情况下,equals方法比较对象的内存地址是否相同。然而,有时我们需要根据对象的具体属性或逻辑来判断对象是否相等,这就需要重写equals方法。
重写equals方法能够满足以下需求:
1. 自定义相等比较规则:通过重写equals方法,我们可以根据对象的特定属性来判断对象是否相等。例如,对于一个Person类,我们可能希望在姓名和年龄相同的情况下认为两个对象相等。通过重写equals方法,我们可以根据姓名和年龄来实现这一相等比较规则。
2. 避免重复对象:在Java中,相同内容的对象可能会被重复创建。通过重写equals方法,我们可以判断对象是否已经存在,从而避免重复创建相同内容的对象。
3. 保证集合操作的正确性:在使用集合类(如List、Set、Map)时,需要依赖equals方法来判断对象是否已经存在于集合中。如果没有重写equals方法,会导致无法正确地判断集合中是否包含某个对象。
需要注意的是,在重写equals方法时,还需要同时重写hashCode方法,以确保当两个对象相等时,它们的哈希码也相等。这是因为在使用哈希结构的集合类(如HashSet、HashMap)时,会先根据对象的哈希码来定位对象所在的位置,然后再使用equals方法来判断是否真正相等。
在总结一下,重写equals方法是为了实现自定义的相等比较规则,避免重复对象的创建,并保证集合类的操作正确性。同时,需要记得重写hashCode方法,以确保哈希码的一致性。
如何重写hashcode和equals方法?
在Java中,Object类中定义了hashCode()和equals()方法。hashCode()方法返回对象的散列码,equals()方法比较两个对象是否相等。如果你自定义了一个类,并且要在该类的实例之间进行比较和查找,那么你需要覆盖hashCode()和equals()方法。
重写hashCode()方法的步骤如下:
1. 声明一个整型变量result并初始化为一个非零的奇数。
2. 对于对象的每个关键域f,计算该域的哈希码c:
a. 如果该域是基本类型,则计算Type.hashCode(f),其中Type是相应基本类型的包装类。
b. 如果该域是一个对象引用,并且该类的equals方法通过递归调用equals的方式比较这个域,则同样递归调用这个域的hashCode()方法。如果这个域的值为null,则返回0。
c. 如果该域是一个数组,则需要对数组的每个元素进行上述操作,可以使用Arrays.hashCode方法。
3. 将计算得到的哈希码c合并到result中,可以使用result = 31 * result + c的方式。
4. 返回result。
重写equals()方法的步骤如下:
1. 首先判断传入的对象是否与当前对象引用相同,如果是则返回true。
2. 判断传入的对象是否为null或者与当前对象的类不同,如果是则返回false。
3. 将传入对象转换为当前类的类型。
4. 对于对象的每个关键域f,检查该域在传入对象和当前对象中的值是否相等。如果所有的关键域都相等,则返回true;否则返回false。
注意:当你重写equals方法时,也应该重写hashCode方法,以便在将对象放入哈希表等数据结构中时能够正确地工作。