在编程语言的宇宙中有一世界叫做
Java
,Java
中有一个超级老祖,叫做Object
, 他是所有类的共同的父类,所有对象均隐性继承了此类。Object
有两个方法,equals()
与hashCode()
; 这两个方法也是隐性的传承给了所有的对象。
一、equals()
1.1 equals()简介
equals()
方法是Java
中的一个方法,用于比较两个对象是否相等。它是在Object
类中定义的,因此所有的Java
类都继承了这个方法。
默认情况下,equals()
方法比较两个对象的引用是否相等,也就是它们是否指向了内存中的同一个对象。这是因为Object
类的equals()
方法实现如下:
java
public boolean equals(Object obj) {
return (this == obj);
}
然而,在实际开发中,我们通常需要根据对象的属性来确定它们是否相等,而不仅仅是比较引用。这就需要我们在自定义类中重写equals()
方法,以便根据业务逻辑来定义相等性比较。
1.2 equals()重写(自定义类对象内容是否相等)
通过重写equals()
方法,我们可以根据自定义的相等性逻辑来比较对象,而不仅仅是比较引用。这样可以提高对象比较的灵活性和准确性。在使用集合类、比较对象等场景时,正确实现equals()
方法非常重要。
在重写equals()
方法时,我们通常需要考虑以下几个方面:
下面是一个示例,演示了如何重写equals()
方法:
java
public class Person {
private String name;
private int age;
// 构造函数、getter和setter方法等省略
@Override
public boolean equals(Object obj) {
// 检查传入的参数是否为null
if (obj == null) {
return false;
}
// 检查传入的参数是否为当前类的实例
if (getClass() != obj.getClass()) {
return false;
}
// 将传入的参数转换为当前类的类型
Person other = (Person) obj;
// 比较对象的属性是否相等
return name.equals(other.name) && age == other.age;
}
}
二、hashCode()
2.1 hashCode()简介
hashCode()
方法是Java中的一个方法,用于返回对象的哈希码(整数值)。它是在 Object
类中定义的,因此所有的 Java
类都继承了这个方法。
哈希码是根据对象的属性计算得出的一个整数值。它通常用于在哈希表等数据结构中进行对象的存储和查找。哈希表是一种根据键值对存储和检索数据的数据结构,它通过将键转换为哈希码来确定存储位置,从而实现快速的数据访问。
在 Java
中,哈希表的实现类(如 HashMap
、HashSet
等)使用了对象的哈希码来决定对象在表中的存储位置。因此,重写equals()
方法时通常也需要重写 hashCode()
方法,以确保相等的对象具有相等的哈希码。
以下是hashCode()
方法的默认实现,来自Object类:
java
public int hashCode() {
return super.hashCode();
}
2.2 hashCode()重写(自定义类对象内容是否相等)
默认情况下,hashCode()
方法返回的是对象的内部存储地址的哈希码,即对象的标识哈希码。然而,这种默认实现通常不满足我们对相等性的要求。
在重写hashCode()
方法时,我们通常需要遵循以下几个原则:
相等的对象必须具有相等的哈希码。这意味着如果
equals()
方法返回true
,则两个对象的hashCode()
方法应返回相同的值。尽量使不相等的对象具有不同的哈希码,以提高哈希表的性能。尽量避免不相等的对象具有相同的哈希码,这会导致哈希冲突,影响查找效率。
哈希码的计算应基于对象的属性。通常可以使用对象的属性值来计算哈希码,例如字符串的哈希码可以使用其字符序列的哈希码计算得出。
下面是一个示例,演示了如何重写hashCode()
方法:
java
public class Person {
private String name;
private int age;
// 构造函数、getter和setter方法等省略
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
注意 :重写
hashCode()
方法时,需要确保与equals()
方法的逻辑一致。这样,当两个对象根据equals()
方法比较相等时,它们的哈希码也应该相等。正确实现
hashCode()
方法可以提高哈希表等数据结构的性能,并确保对象能够在集合类中正确存储和检索。
三、思考:两个对象的hashCode()相同,则 equals()是否也一定为true?
结论 :两个对象 equals()
相等,则它们的 hashCode()
必须相等,如果两个对象的hashCode()
相同,则 equals()
不一定为 true
。
3.1 扩展知识
在Java
中,关于hashCode()
方法有一些常规协定和约定俗成的规则。这些规则有助于确保正确实现hashCode()
方法,并使其在哈希表等数据结构中正常工作。
以下是hashCode()
方法的常规协定 (非强制规定):
一致性 :在对象没有发生属性变化的情况下,多次调用
hashCode()
方法应该始终返回相同的值。只有当对象的属性发生变化时,hashCode()
方法的返回值才可以改变。相等性一致性 :如果两个对象根据
equals()
方法比较相等,那么它们的hashCode()
方法必须返回相同的值。即使两个对象的属性发生变化,只要它们仍然相等,它们的哈希码必须保持一致。哈希码分布均匀性:不相等的对象应该具有不同的哈希码,以减少哈希冲突的可能性,提高哈希表等数据结构的性能。尽量使哈希码在整个可能的范围内均匀分布,以避免热点区域的聚集。
性能考虑 :
hashCode()
方法的计算应该高效,尽量避免复杂的操作和耗时的计算。由于哈希码通常在哈希表等数据结构中频繁使用,性能较低的hashCode()
方法可能会影响整体性能。
四、总结
在Java
中,equals()
和hashCode()
方法是用于对象相等性比较和哈希表存储的重要方法。
这两个方法在一起使用,可以保证对象在哈希表等数据结构中正确存储和检索,并确保对象的相等性比较得到正确的结果。它们在集合类(如HashMap
、HashSet
)中广泛使用,以提供高效的元素存储和查找功能。
希望本文对您有所帮助。如果有任何错误或建议,请随时指正和提出。
同时,如果您觉得这篇文章有价值,请考虑点赞和收藏。这将激励我进一步改进和创作更多有用的内容。
感谢您的支持和理解!