提到equals 和== 很多人会习惯性的说,==是比较地址(引用),equals 是比较值。是这样吗?
先看下Object类的equals()方法
public boolean equals(Object obj) {
return (this == obj);
}
这里很明显是比较地址(引用)啊,那为什么会有比较内容值这说法呢??
因为很多类像String等对Object类的equals()方法进行了重写,String的equals()代码如下:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
hashCode():
在Object类中的定义为:
public native int hashCode();是一个本地方法,返回的对象的地址值。
String类中重写了:
public int hashCode() {
int h = hash;
if (h == 0) {
int off = offset;
char val[] = value;
int len = count;
for (int i = 0; i < len; i++) {
h = 31*h + val[off++];
}
hash = h;
}
return h;
}
equals原则:
1.对于任何引用类型,o.equals(o) == true成立
2.如果 o.equals(o1) == true 成立,那么o1.equals(o)==true也一定要成立
3.如果 o.equals(o1) == true 成立且 o.equals(o2) == true 成立,那么o1.equals(o2) == true 也成立
4.如果第一次调用o.equals(o1) == true成立再o和o1没有改变的情况下以后的任何次调用都成立
5.o.equals(null) == false
两者关系:
1、相等的对象必须具有相等的哈希码(或者散列码)。
2、如果两个对象的hashCode相同,它们并不一定相同。
“一个很常见的错误根源在于没有覆盖hashCode方法,在每个覆盖了equals方法的类中,也必须覆盖hashCode方法。”
以下约定内容摘自Object规范[JavaSE6]:
1. 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
2. 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
3. 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。