关于equals()和hashCode()方法的相关知识
在Java中,每个类都继承自`Object`类,并且`Object`类中定义了两个方法`equals()`和`hashCode()`。这两个方法是非常重要的,用于比较对象和生成散列码。
首先,我们来看一下`equals()`方法。该方法在`Object`类中被定义为比较两个对象是否相等。默认情况下,`equals()`方法使用的是比较对象的内存地址,即判断两个对象是否引用的是同一块内存空间。但是,你可以通过在自定义类中重写`equals()`方法来改变默认的比较逻辑。
重写`equals()`方法时应遵循以下规则:
1. 对称性:如果`x.equals(y)`返回`true`,那么`y.equals(x)`也应返回`true`。
2. 反射性:对于任何非空的引用值`x`,`x.equals(x)`应返回`true`。
3. 传递性:如果`x.equals(y)`返回`true`,且`y.equals(z)`返回`true`,则`x.equals(z)`也应返回`true`。
4. 一致性:如果两个对象`x`和`y`没有发生变化,那么多次调用`x.equals(y)`应该返回相同的结果。
5. 对于任何非空引用值`x`,`x.equals(null)`应返回`false`。
同时,为了保持与`equals()`方法的一致性,我们还需要重写`hashCode()`方法。散列码用于指示对象的存储地址,它是一个整数值。在默认情况下,`hashCode()`方法返回对象的散列码,其中散列码被定义为对象的内存地址。但是,如果你重写了`equals()`方法,那么就必须同时重写`hashCode()`方法以保持一致性。
在重写`hashCode()`方法时应遵循以下规则:
1. 如果两个对象根据`equals()`方法是相等的,那么它们的散列码必须是相等的。
2. 如果两个对象根据`equals()`方法不相等,不要求它们的散列码一定不相等(但是,不同的散列码应该能够提高散列容器的性能)。
3. 在应用程序的执行期间,对于同一对象多次调用`hashCode()`方法必须返回相同的整数值,前提是对象上的equals比较中所用的信息没有被修改。
重写`hashCode()`方法时,可以采用以下步骤:
1. 声明一个int类型的变量result,并将其初始化为对象的某个非零常数值。
2. 对象的每个关键域进行哈希计算,可以使用`Objects.hashCode()`方法。
3. 将上一步得到的哈希码与result合并,可以通过result = 31 * result + fieldHashCode的方式实现。
4. 对于实例中为null的引用域,可以单独考虑,赋一个常量值。
在使用`equals()`和`hashCode()`方法时,还有一些注意事项:
1. 当重写了`equals()`方法时,必须同时重写`hashCode()`方法。
2. 两个对象的散列码相等并不代表这两个对象相等。
3. 如果两个对象的`equals()`方法返回`false`,它们的散列码不应相等。
4. 如果两个对象的`equals()`方法返回`true`,它们的散列码应相等,但相等的散列码不一定代表对象的`equals()`方法返回`true`。
总之,`equals()`和`hashCode()`方法在Java中是相辅相成的。`equals()`方法用于比较对象的内容是否相等,而`hashCode()`方法用于生成散列码,用于散列容器的存储和检索。在重写这两个方法时,需要遵循一定的规则,以确保逻辑的一致性。只有在正确地使用`equals()`和`hashCode()`方法的情况下,才能***限度地发挥它们的作用。