equals() & hashCode()
i. 首先,简单介绍一下具体用法
- boolean equals(Object obj) – 用于判断调用对象是否与参数对象相等
– $\color{red}该方法默认比较两个对象的地址,与 “==” 等效$
– 若希望比较对象的内容,则需要进行方法的重写
– 若该方法重写了,则应该去重写hashCode()方法,以维护 hashCode 方法的常规协定 - int hashCode() – 用于获取调用对象的哈希码值(内存地址和编号)并返回
– 若两个对象调用equals()方法相等,则各自调用该方法得到的哈希码值必须相同
– 若两个对象调用equals()方法不相等,则各自调用该方法的结果可以相同,但是最好不相同
ii. 一个案例带你搞懂 equals() 和 hashCode()
- 首先,我们创建一个Student类// Student类封装
public class Student {private int id;
private String name;public Student() {
super();
}public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}public int getId() {
return id;
}
public void setId(int id) {
if (id > 0) {
this.id = id;
} else {
System.out.println(“学号不合理!”);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public class TestStudent {public static void main(String[] args) {
Student s1 = new Student(1001, “老王”);
Student s2 = new Student(1001, “老王”);System.out.println(s1 + ” ” + s2);
// 调用equals方法来判断两个对象是否相同,这里默认从Object类中继承boolean b1 = s1.equals(s2);
System.out.println(“b1 = “+b1); // b1 = false
System.out.println(s1 == s2); // false
}}Euqals.Student@2f92e0f4 Euqals.Student@28a418fc
b1 = false
false// Student类封装
public class Student {private int id;
private String name;public Student() {
super();
}public Student(int id, String name) {
super();
this.id = id;
this.name = name;
}public int getId() {
return id;
}
public void setId(int id) {
if (id > 0) {
this.id = id;
} else {
System.out.println(“学号不合理!”);
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}@Override
public boolean equals(Object obj) {
// 1. 若两个对象的地址一样,则内容一定相同
if (this == obj) {
return true;
}
// 2. 若调用对象不为空, 参数对象为空,则内容一定不相同 (如t1.equals(null))
else if (obj == null) {
return false;
}
// 3. 若参数对象和调用对象类型一致,则由学号来决定两个对象内容是否相同
else if (obj instanceof Student) {Student s = (Student)obj;
if (this.getId() == s.getId()) {
return true;
} else {
return false;
}
}
// 4. 若参数对象和调用对象类型不一致,则内容一定不相同
else {
return false;
}
}System.out.println(“你好”.equals(“你好”)); // truetrue - 在TestStudent类中进行测试
- 显然,因为equals方法默认比较的是地址,这里s1与s2地址不同,输出为false。那么,如果我们想要另两个对象学号相同时,使用equals 方法时输出为true 应该怎么做呢,很显然,equals方法是属于Object类的,那么我们只要在Student类中对其进行重写即可
- 这里,我们对4中情况进行了考虑,我们再次运行TestStudent代码,发现此时输入了true,因为当我们重写equals方法后,则调用子类重写以后的版本,比较内容。
- 在这里,我们会想到String类,那么我们对String对象调用equals方法会输出什么呢?
- 这里输出的是true,我们知道这是两个String对象,输出不应该是false吗?根据前面所讲的,我们明白了,原来 $\color{red}String类中也对equals方法进行了重写$, 那么我们就明白了。到这里就完了吗?不,还没有,前面我们说过,一般为了维护hashCode方法的常规协定,我们要在Student类中重写 hashCode方法 // 为了保证和equals方法结果一致性,需要重写hashCode
@Override
public int hashCode() {// return getId();
// 随便定义,为了保持ID相同
// 维护hashCode方法的常规协定
int type = 12;
return type*31 + getId();
} - 我们在TestStudent类中进行测试 // 调用从Object类中继承的hashCode方法来获取对应的哈希码
// 当Student类中重写hashCode方法后,则调用重写以后的版本
int res = s1.hashCode();
System.out.println(“res = ” + res);res = s2.hashCode();
System.out.println(“res = ” + res);res = 1373
res = 1373 - 这里就达到了我们想要的结果,你Get到了吗?
喜欢就关注博主吧,你的关注点赞是对博主最大的鼓励!:smile: