之前看面试题的时候发现了一个遗忘的知识点,就是hashcode()与equals().
忽然之间弄不明白hashcode与equals分别比的是什么?谁先执行?什么情况下都执行?什么情况下都只执行一个?
为了弄懂这些我特意去网上查阅了大量的博客与文章。发现了都是讲概念不讲原理,空口套话谁不会,如果概念再加上实质的理解岂不更好?所以今天就写了这篇文章,当然内容肯定也有不妥的地方还希望网友指出,讨论,咱们共同进步一起成长。
好,不多说!我们先记住一段话“equals()==true则hashcode()==true,hashcode()==true则不一定equals()==true”
那么我们就不去object查找源码了,因为这会误导我们的思维。我们看一下我们重写之后的代码吧:
public class Users {
private String username;
private String password;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((username == null) ? 0 : username.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;
Users other = (Users) obj;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
}
网上有人说hashcode比较的实地址,但又一老说 “equals()==true则hashcode()==true,hashcode()==true则不一定equals()==true”,当时我就十分费解,难道两个内容一样的对象要存在一个地址空间吗,这不就成了同一个对象了吗,但我们确实是new的不同的对象,当时我就不停的想啊想啊,还是想不明白,后来要不看一下源码吧,发现也没多大用处,那就自己写一个类重写这里边的方法看看他的重写过程,发现一下子解开了我的疑惑。
我们看这个hashcode究竟做了什么事
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((password == null) ? 0 : password.hashCode());
result = prime * result + ((username == null) ? 0 : username.hashCode());
return result;
}
我们发现他并没有去比较地址而是返回对象中的内容的hash值。那么我们再看看equals吧:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Users other = (Users) obj;
if (password == null) {
if (other.password != null)
return false;
} else if (!password.equals(other.password))
return false;
if (username == null) {
if (other.username != null)
return false;
} else if (!username.equals(other.username))
return false;
return true;
}
发现他也是对对象内容进行比较,那我们实现equals时候必须实现hashcode吗,答案是可以不实现,但建议实现为啥那么那?
我们运行流程的时候发现,当有hashcode重写实现的时候或者走object的hashcode方法的时候进行对象间比较程序总是先走hashcode然后走equals,其中equals不是必须走的而是当两个对象比较的hash值一直的时候才会走。为啥会这样那?
我们都知道机器底层其实识别的只有01代码,那么他处理hash值得速度是不是更快一些那,对系统性能也就提高一点了,而由于转换为hash值可能会重复的比如“2+4==3+3”,所以equals就是当前面的方法解决不了问题了才会登场。这也就很好的解释了前面的一句话“equals()==true则hashcode()==true,hashcode()==true则不一定equals()==true“
那么我们就知道谁先执行了?为了性能当然先执行hashcode;
什么情况下都执行?当然是hashcode自己解决不了的时候,什么时候解决不了看上边;
什么情况下只执行一个?当hashcode自己能够解决的时候;
有没有只执行equals的时候?答案是没有,就算你不去实现hashcode我们的老大object也有的,只不过返回永远是一样的所以“强制”去执行equals;
那么到底hashcode与equals分别比的是什么?
这两个只不过是解决两个对象是否想等的两个策略或者两个形式,只不过比较的方式不同,互相依赖也不依赖。
感觉我说的有问题的朋友请求骚扰。