Java Object 类中存在hashcode()方法以及equals方法
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
hashCode方法是一个本地方法用于获取一个对像的hash值,equals方法用于比较两个对象的地址是否相等。
我们判断一个对象相等的条件是:
两个对象的hash值相等且equals方法返回ture.
例如String类重写了equals方法,用于比较内容。
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
从代码可以看出,如果对象地址相同直接返回true,否则比较内容,如果内容相同则返回true否则返回false.
在没有重写equals方法前加入有两个对象 str1 str2 ,两者的hash值大概率是不相等的,equals 也是不等的,重写后equals相等,那么hash值也应相等,所以要重新写hashcode(),利用字符串的每一位做hash那么两个内容相同的字符串hash必定相同。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
在Java API文档中关于hashCode方法有以下几点规定:
1 在java应用程序执行期间,如果在equals方法比较中所用的信息没有被修改,那么在同一个对象上多次调用hashCode方法时必须一致地返回相同的整数。如果多次执行同一个应用时,不要求该整数必须相同。
2 如果两个对象通过调用equals方法是相等的,那么这两个对象调用hashCode方法必须返回相同的整数。
3. 如果两个对象通过调用equals方法是不相等的,不要求这两个对象调用hashCode方法必须返回不同的整数。但是程序员应该意识到对不同的对象产生不同的hash值可以提供哈希表的性能。
应用于map类型的数据结构时特别明显:
Map中的key值是根据hashcode实现的,eg,set集合,如果重写了equals方法,如String类,如果不重写hashcode()则可能会存入两个相同的字符串,这和set的集合特性不一致。