1.equals与hashcode间的关系
1.如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;
2.如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)
2.为什么要这样设计
为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的次数,这对比需要比较的数量很大的效率提高是很明显的,一个很好的例子就是在集合中的使用;
我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,但靠equals方法一样比较的话,如果原来集合中以后又10000个元素了,那么放入10001个元素,难道要将前面的所有元素都进行比较,看看是否有重复,欧码噶的,这个效率可想而知,因此hashcode就应遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据只要看对应的hashcode地址上是否有值,那么就用equals比较,如果没有则直接插入,只要就大大减少了equals的使用次数,执行效率就大大提高了。继续上面的话题,为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode确实不相同的
3.什么时候要重载equal方法?
Object的equal方法默认是两个对象的引用的比较,意思就是指向同一内存,地址则相等,否则不相等;如果你现在需要利用对象里面的值来判断是否相等,则重载equal方法。
public static void main(String[] args) {
Student student1= new Student(11,"basketball");
Student student2= new Student(11,"basketball");
if(student1.equals(student2)){
System.out.println(true);
}else {
System.out.println(false);
}
if(student1.hashCode() == student2.hashCode()){
System.out.println(true);
}else {
System.out.println(false);
}
上面最终输出的都是false,但有时候我们希望只要Object的属性都相等,就认为他们equal。因此,我们需要重写equals方法来
实现我们的需求。
@Override
public boolean equals(Object obj) {
if(obj instanceof Student){
Student student = (Student)obj;
if(student.getAihao().equals(this.aihao)&&student.getJibie() == (this.jibie)){
return true;
}else {
return false;
}
}
return false;
}
此时分别输出true和false
因此,还需重写hashcode()方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((jibie == null) ? 0 : jibie.hashCode());
result = prime * result + ((aihao == null) ? 0 : aihao.hashCode());
return result;
}
此时输出的都为true
---