前言
我们知道,所有的类都继承了Object类,所以每个类都拥有了Object类里面的equals方法和hashCode方法:
- Object里的equals方法:
public boolean equals(Object obj) {
return (this == obj);
}
- Object里的hashCode方法:
public native int hashCode();
- 我们常说的“==”和equals的区别,其中的equals一般指的是String类中被重写后的equals方法,而Object中的equals实际上还是比较对象的地址(看上面Object源码使用了 “= =”),并不是两个对象中的值。
- 那么我们如果如果要比较对象是否相等的话,我们就可以重写它的equals方法和hashCode方法(hashCode有什么作用呢?我们下面再说)。
1.写一个User类,并重写equals方法和hashCode方法:
package com.wei;
public class User {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public User(String name, String age) {
super();
this.name = name;
this.age = age;
}
public User() {
}
//重写equals方法
@Override
public boolean equals(Object obj) {
if(this == obj) { //地址相同
return true;
}
if(obj == null) {
return false; //为空返回false
}
if(obj instanceof User) { //instanceof判断对象实例obj是否属于User
User o = (User)obj;
//调用比较字段方法
if(equalsStr(this.name,o.name)
&& equalsStr(this.age,o.age)) {
return true;
}
}
return false;
}
private boolean equalsStr(String str1,String str2) { //写一个比较字段方法
if((str1 == null) && (str2 ==null)) {
return true;
}
if(!(str1==null) && str1.equals(str2)) {
return true;
}
return false;
}
//重写hashCode方法
public int hashCode() {
int result = 17;
result = 31 * result + (name == null ? 0 : name.hashCode());
result = 31 * result + (age == null ? 0 : age.hashCode());
return result;
}
}
2.然后我们可以写一个测试类去调用测试一下:
package com.wei;
public class UserTest {
public static void main(String[] args) {
User a = new User();
User b = new User();
a.setAge("18"); //设置a,b引用变量中的age
b.setAge("18");
a.setName("weiwei"); //设置a,b引用变量中的name
b.setName("weiwei");
boolean flag = a.equals(b);
System.out.println(flag);
}
}
- 我们可以看到输出结果:
- 既然比较两个对象是否相等,使用的是 equals 方法,那么只要重写了 equals 方法就好了,干嘛又要重写 hashCode 方法呢?hashCode作用是什么呢?其实hashCode作用跟equals稍有不同,hashCode是根据对象的内存地址经过哈希算法得出一串数字。当然,两个不同的对象地址经过计算是有可能得出一样的结果,我们这里重写的hashCode方法只是调用了String中的hashCode方法,将对象中的每个属性的值经过计算返回一串数字,最后返回,相同值的对象返回的hashCode值的是一样的,但是相同hashCode值的对象却有可能不一样。所以:
- 当两个对象hashCode不同时候,两个对象已经确定不是相同的值,不需要再比较了,提高了效率。
- 当hashCode相同的时候,需要再经过equals方法比较来确定是否值的内容相同。