1、在Object类中的定义为:
public native int hashCode();
是一个本地方法,返回的对象的地址值。
可是,一样的思路,在String等封装类中对此方法进行了重写。方法调用获得一个计算公式获得的 int值。
2、在重写任何类得hashcode方法时必须遵循如下几点:
一、在Java应用的同一次执行过程当中,同一对象被屡次调用,则他们的hashcode值必然相同。
而对于同一个应用的两次不一样的调用,它们的Hashcode值能够相同,也有可能不一样。
二、对于两个对象来讲,若是他们的equals方法比较返回true,那么这两个对象的hashcode必然相同。
这也解释了为何String类中,若是两个对象的equals方法相同,则他们的hashcode值必定相同。
三、对于两个对象来讲,若是使用equals方法返回为false,则他们的hashcode的值有可能相等也可能不等,
(若是不一样会提升性能,由于在集合中类判断两个对象是否相等,若是其hashcode不等就直接不用判断equals方法了)
四、对于Object对象来讲,不一样的Object对象的hashcode是不一样的,它们返回的是对象的地址,
equals返回的也是对象的地址。因此在本身定义的类中若是要添加到集合对象中,
最好是要重写hashcode和equals方法,否则会自动继承自Object类中的两个方法根据对象地址来判断。
在重写本身定义的类时,一般是在类中的根据某个值如name.hashcode();来进行判断。
3、以HashSet 为例:
当咱们使用HashSet时,hashCode()方法就会被获得调用,判断已经存储在集合中的对象的hashCode值是否与所增长。
对象的hashCode值一致,若是“不一致”则直接加进去(不用比较equals()提升效率),若是一致,则进行equals方法的比较,若是返回true,代表集合里面已经有这个对象,不能添加进去了。若是是false表是集合里面没有这个对象,则能够加进去。因此在重写hashcode()或者equals() 方法的任何一个方法时,必须重写另一个。
示例代码:
/**
* People 手工重写hashcode方法和equals方法 根据name来判断 两个对象是否相等。
*/
class People {
private String name;
public People(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
//若是是本身
if(this==obj){
return true ;
}
//若是是空
if(obj==null ){
return false;
}
//比较两个People的名字是否相同
if(obj!=null && obj instanceof People){
if(((People)obj).name.equals(this.name))
return true ;
}
return false;
}
@Override
public int hashCode() {
// String的hashcode原本就是用来比较两个字符是否相等
return name.hashCode();
}
}
最近看了Object类的源码,对hashCode() 和equals()方法有了更深的认识。重写equals()方法就必须重写hashCode()方法的缘由,从源头Object类讲起就更好理解了。java
先来看Object关于hashCode()和equals()的源码:程序员
光从代码中咱们能够知道,hashCode()方法是一个本地native方法,返回的是对象引用中存储的对象的内存地址,而equals方法是利用==来比较的也是对象的内存地址。从上边咱们能够看出,hashCode方法和equals方法是一致的。还有最关键的一点,咱们来看Object类中关于hashCode()方法的注释:
简单的翻译一下就是,hashCode方法通常的规定是:
再简单的翻译一下第二三点就是:hashCode()和equals()保持一致,若是equals方法返回true,那么两个对象的hasCode()返回值必须同样。若是equals方法返回false,hashcode能够不同,可是这样不利于哈希表的性能,通常咱们也不要这样作。重写equals()方法就必须重写hashCode()方法的缘由也就显而易见了。数组
假设两个对象,重写了其equals方法,其相等条件是属性相等,就返回true。若是不重写hashcode方法,其返回的依然是两个对象的内存地址值,必然不相等。这就出现了equals方法相等,可是hashcode不相等的状况。这不符合hashcode的规则。下边,会介绍在集合框架中,这种状况会致使的严重问题。app
class A {
String certificate;框架
public A(String certificate) {ide
this.certificate = certificate;
}性能
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
A other = (A) obj;
if (certificate == null) {
if (other.certificate != null)
return false;
} else if (!certificate.equals(other.certificate))
return false;
return true;
}ui
}this
class B {
String certificate;// 身份证号spa
public B(String certificate) {
this.certificate = certificate;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((certificate == null) ? 0 : certificate.hashCode());
return result;
}
}
class C {
String certificate;
public C(String certificate) {
this.certificate = certificate;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((certificate == null) ? 0 : certificate.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;
C other = (C) obj;
if (certificate == null) {
if (other.certificate != null)
return false;
} else if (!certificate.equals(other.certificate))
return false;
return true;
}
}