Java 中 hashCode 和 equals 方法是什么?它们与 == 操作符有什么区别?
回答重点
hashCode、equals
和 ==
都是 Java
中用于比较对象的三种方式,但是它们的用途和实现还是有挺大区别的。
hashCode
用于散列存储结构中确定对象的存储位置。可用于快速比较两个对象是否不同,因为如果它们的哈希码不同,那么它们肯定不相等。equals
用于比较两个对象的内容是否相等,通常需要重写自定义比较逻辑。==
用于比较两个引用是否指向同一个对象(即内存地址)。对于基本数据类型,比较它们的值。
扩展知识
hashCode
方法返回对象的哈希码(整数),主要用于支持基于哈希表的集合,用来确定对象的存储位置,如 HashMap、HashSet
等。
Object
类中的默认实现会根据对象的内存地址生成哈希码(native
方法)。
在 Java
中,hashCode
方法和 equals
方法之间有一个 " 合约 ":
- 如果两个对象根据
equals
方法被认为是相等的,那么它们必须具有相同的哈希码。 - 如果两个对象具有相同的哈希码,它们并不一定相等,但会被放在同一个哈希桶中。
equals
用于比较两个对象的内容是否相等。Object
类中的默认实现会使用 == 操作符来比较对象的内存地址。
通常我们需要在自定义类中重写 equals
方法,以基于对象的属性进行内容比较。比如你可以自定义两个对象的名字一样就是相等的、年龄一样就是相等,可以灵活按照需求定制。
如果两个对象的 equals
方法返回 true,则它们的
hashCode
方法必须返回相同的值,反之则不需要。
对于 equals
定义的比较,实际上还有以下五个要求:
- 自反性:对于任何非空引用值
x
,x.equals(x)
必须返回true
。 - 对称性:对于任何非空引用值
x
和y
,如果x.equals(y)
返回true
,则y.equals(x)
也必须返回true
。 - 传递性:对于任何非空引用值
x
、y
和z
,如果x.equals(y)
返回true
且y.equals(z)
返回true
,则x.equals(z)
也必须返回true
。 - 一致性:对于任何非空引用值
x
和y
,只要对象在比较中没有被修改,多次调用x.equals(y)
应返回相同的结果。 - 对于任何非空引用值
x
,x.equals(null)
必须返回false
。
==
==
操作符用于比较两个引用是否指向同一个对象(即比较内存地址),如果是基本数据类型,==
直接比较它们的值。
hashCode、equal 和 == 的区别
hashCode
定义:
hashCode()
是 java.lang.Object
类中的方法,用于返回对象的缓存值。
作用:
- 在哈希表(如
HashMap
、HashSet
)中快速查找对象。 - 相同的对象应该具有相同的哈希值,但不同的对象可能具有相同的哈希值(哈希冲突)。
注意:
- 如果重写了
equals
方法,通常需要同时重写hashCode
,并遵循以下规则:- 如果对象用
equals
比较返回true
,它们hashCode
必须两个相同。 - 如果对象用
equals
比较返回false
,它们的两个hashCode
可以相同,但尽量避免(减少冲突冲突)。
- 如果对象用
示例:
@Override
public int hashCode() {return Objects.hash(id, name); // 根据 id 和 name 计算哈希值
}
equal
定义:
equals()
用于比较两个对象的内容是否相同的方法。
作用:
- 默认实现(在
Object
类中)比较的是两个对象的引用是否相同(地址相同)。 - 在子类中可以重写
equals
,根据具体需求定义 " 可行 " 的逻辑。
注意:
equals
方法在集合操作中很重要,比如在HashSet
或作为HashMap
的键时。- 重写
equals
时,必须遵守以下规则:- 自反性:
x.equals(x)
必须为true
。 - 价格:
x.equals(y)
和y.equals(x)
结果相同。 - 传递性:如果
x.equals(y)
和y.equals(z)
为true
,则x.equals(z)
也为true
。 - 一致性:多次调用
x.equals(y)
时结果一致,忽略对象状态改变。 - 与
null
的比较总是返回false
。
- 自反性:
示例:
@Override
public boolean equals(Object obj) {if (this == obj) return true;if (obj == null || getClass() != obj.getClass()) return false;Person person = (Person) obj;return id == person.id && Objects.equals(name, person.name);
}
==
定义:
==
是 Java 的操作,用于比较两个变量的值。
作用:
- 对于基本数据类型,
==
是比较值。