您现在的位置是:架构师问答 >
架构师问答
为什么在比较两个对象时,要同时使用 equals() 和 hashCode() 方法?
本 文 目 录
当我们使用Java中的集合框架(如HashMap、HashSet等)存储或比较对象时,通常会涉及到equals()和hashCode()这两个方法。如果只覆盖其中一个方法而不覆盖另一个,可能会导致意外的行为。下面我们来详细解释原因,并通过代码案例进行说明。
1. 一致性原则
对象在equals()方法中被视为相等,那么在hashCode()方法中也应该返回相同的哈希码。如果不这样做,会导致对象在集合中的行为出现异常。
2. 提高性能
在使用HashMap等数据结构时:
hashCode()方法用于快速定位元素可能存在的桶;
而equals()方法用于确认是否真的找到了我们要的元素。
如果hashCode()返回了不同的值,即使equals()返回true,HashMap也会认为这两个对象是不同的。
代码案例:
假设有一个Person类,只覆盖了equals()方法,而没有覆盖hashCode()方法。
public class Person {
private String name;
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return Objects.equals(name, person.name);
}
// hashCode方法没有被覆盖
}
如果我们尝试将两个equals的Person对象加入到HashSet中:
HashSet<Person> set = new HashSet<>();
Person p1 = new Person();
p1.setName("John");
Person p2 = new Person();
p2.setName("John");
set.add(p1);
set.add(p2);
System.out.println(set.size()); // 输出结果是2而不是1
尽管p1和p2在逻辑上是相等的(因为name都是"John"),但HashSet会认为它们是不同的对象,因为它们的hashCode值不同(默认是对象的内存地址)。
为了避免这种情况,我们需要在重写equals()方法的同时也重写hashCode()方法,确保逻辑相等的对象具有相同的哈希码。
** 所以完整的重写应如下:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
这样,上述代码中的set.size()就会返回1,因为HashSet正确地认为两个对象是相等的。
- 上一篇
[解决方案] cmd上ping的通但telnet不了
cmd上ping的通但telnet不了,基本上主要是由于:防火墙限制、安全配置端口未开放、网络设备限制等三类原因导致。大部分情况下,主要是由于安全端口未放开导致的,所以这类问题,建议先从安全端口出开始排查。## 三、ping命令与telnet命令的区别与联系* ping命令:用于测试网络连通性,通过发送ICMP包来检测目标主机是否可达。ping命令只关心网络层是否连通,不关心应用层的端口是否开放。
- 下一篇
Java中equals()和hashCode()的联系?
`equals()`和`hashCode()`两个方法在Java中都具有重要地位。它们之间有着微妙的联系,并且对于Java集合框架和对象比较来说,二者都至关重要。