首先:
了解equals()方法和hashCode()方法关系/规定:
1. 如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同!!!!;
2. 如果两个对象不同(即用equals比较返回fase),那么它们的hashCode值可能相同也可能不同;
3. 如果两个对象的hashCode相同(存在哈希冲突),那么它们可能相同也可能不同(即equals比较可能是false也可能是true)
4. 如果两个对象的hashCode不同,那么他们肯定不同(即用equals比较返回false)
然后:
1、equals()方法和hashCode()方法分别是用来做什么的?
equals()方法:
public boolean equals(Object obj) {
return (this == obj);
}
在Object类源码中,equals()其底层是使用了“==”来实现,也就是说通过比较两个对象的内存地址是否相同判断是否是同一个对象。很明显,该方法就是用来判断两个对象是否是同一个对象。
hashCode()方法:
哈希值的计算利用的是内存地址。
2、实际应用中我们需要的是什么?
但在实际应用时,有时我们只需两个对象的内容相等我们就认为他们是同一个对象,而不是通过内存地址判断;
为了满足这一要求就得重写equals()方法:
public class Student {
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// 省略 get,set方法...
}
public class hashTest {
@Test
public void test() {
Student stu1 = new Student("Jimmy",24);
Student stu2 = new Student("Jimmy",24);
System.out.println("两位同学是同一个人吗?"+stu1.equals(stu2));
System.out.println("stu1.hashCode() = "+stu1.hashCode());
System.out.println("stu1.hashCode() = "+stu2.hashCode());
}
}
执行结果:
两位同学是同一个人吗?true
stu1.hashCode() = 71578563
stu1.hashCode() = 71578563
实现了上面讲的:如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;
只重写 equals() 方法,不重写 hashcode() 方法:
执行结果:
两位同学是同一个人吗?true
stu1.hashCode() = 379110473
stu1.hashCode() = 99550389
可以看到equals相等但是hashcode不一定相等;这是因为不重写hashcode,那么Student类的hashcode方法就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然此时s1!=s2,故两者的hashcode不一定相等。
这就不符合:如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同。
所以重写equals的同时也要重写hashcode。