java中的==、equals方法和hashCode方法
一、==和equals的区别
1、==比较运算符
(1)基本数据类型:比较的是值是否相等
(2)引用数据类型:比较的是地址是否一样
2、equals[object]方法
(1)基本数据类型:不可以使用equals进行比较
(2)引用数据类型:没有重写过equals方法则使用object中的equals方法,本质上是使用==,比较的是地址
(3)String类型:源码重写了equals方法,先比较两个的地址是否一样,一样就返回true,不一样再比较值是否一样(代码如下)。
public boolean equals(Object anObject) {
//先比较地址
if (this == anObject) {
return true;
}
//地址不一样再来看是不是String类型,然后对值进行比较
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;
}
二、Object中的hashCode方法及equals方法和hashCode方法的重写
hashCode方法:没有被重写的object中原生的hashCode值是根据内存地址换算出来的一个值。
在Object.hashCode()中对hashCode方法的解释:
1、在一个应用程序执行期间,同一个对象上多次调用hashCode,则返回的值都是相同的整数,前提是该对象上的equals比较中的信息没有被修改。
2、如果两个对象根据equals方法是相等的,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果。
3、如果两个对象根据equals方法是不相等的,那么在两个对象中的每个对象上调用hashCode方法不要求必须产生不同的整数结果。但是,为不相等的对象产生不同的整数结果可能会提高哈希表的性能。
4、通常是通过将对象的内部地址转换为整数来实现hashCode值,但是你也可以自己实现hash算法,即重写hashCode方法。
也就是说:
两个对象根据equals方法是相等的,那么他们的hashCode值也相等;
两个对象根据equals方法是不相等的,那么他们的hashCode值可以相等也可以不相等;
两个对象hashCode值相等,他们的equals不一定相等;
为什么重写equals方法后也要重写hashCode方法?
在业务中有时候不需要严格意义上的相等,只需要满足业务要求的对象相等就可以,所以我们就需要根据我们的业务来重写equals方法。
我们重写了equals方法后,如果没有重写hashCode方法,就违反上面说的第2点,所以我们还需要再重写hashCode方法。
String类中重写的hashCode方法:
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;
}
在Object类中关于equals方法和hashCode方法的约定:
/**
* hashCode---java.lang.Object
* 1、只要在Java应用程序执行期间在同一对象上多次调用它,hashCode方法就必须始终返回相同的整数,
* 前提是在该对象的equals比较中使用的信息没有被修改。 从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。
* 2、如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
* 3、根据equals(java.lang.Object)方法,如果两个对象不相等,则在两个对象中的每一个上调用hashCode方法不需要产生不同的整数结果。
* 但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
* 4、在合理可行的范围内,由类Object定义的hashCode方法确实为不同的对象返回不同的整数。
* (通常通过将对象的内部地址转换为整数来实现,但是这种实现技术对于Java编程语言来说不是必须的。
*/
/**
* equals---java.lang.Object
* 指示其他某个对象是否与此对象“相等”。
* equals方法对非null对象引用实现对等关系:
* 1、自反性:对于任何非空参考值x,x.equals(x)应该返回true。
* 2、对称性:对于x和y的任何非空引用值,当且仅当y.equals(x)}返回true时,x.equals(y)才返回true。
* 3、可传递性:对于x,y和z的任何非空引用值,如果x.equals(y)返回true,而y.equals(z)返回true,则x.equals(z)应该返回true。
* 4、一致性:对于任何非空引用值x和y,如果未修改对象的equals比较中使用的信息,则多次调用x.equals(y)始终返回true或始终返回false。
* 对于任何非null的参考值,x,x.equals(null)应该返回false。
* 类Object的equals方法在对象上实现了最有区别的对等关系。 也就是说,对于任何非空参考值x和y,当且仅当x和y引用相同的对象(x == y的值为true)时,
* 此方法才返回true。
* 请注意,通常有必要在重写此方法时重写hashCode方法,以维护hashCode方法的常规协定,该协定规定相等的对象必须具有相等的哈希码。
*/
写在最后:
- 如果文章中有错误或是表达不准确的地方,欢迎大家评论中指正,以便我完善。
- 文章我也会根据所学到新的知识不断更新。