Java中 hashCode 和 equals 重写问题
== 和equals区别 ?
== 是一种逻辑运算符,返回布尔值;
- 两边为基本数据类型时,比较的是值;
- 两边为对象时,比较的是对象的地址;
equals(Object obj)
是Object类的一个方法,返回布尔值;
- 只能比较对象,不能比较基本数据类型,因为equals方法的本质是Object提供的一个对象比较方法;
- 默认其比较的是两个对象的地址,和==具有相同功能;
对象地址 和 hashCode区别 ?
com.bjpowernode.Student@15615099
为对象地址,358699161
为对象hashCode;
@Test
public void test01(){
Student student=new Student();
System.out.println(student); // com.bjpowernode.Student@15615099
System.out.println(student.hashCode()); // 358699161
}
hashCode和equals区别 ?
Object类中的hashCode方法:
它的实现与本地机器有关,默认返回的是对象存储的物理位置的hash计算值,所以默认情况下,hashCode相等的对象 地址一定相等,即为同一对象。
public native int hashCode();
Object类中的equals方法:
默认比较的是两个对象的地址,
public boolean equals(Object obj) {
return (this == obj);
}
为什么要重写equals ?
默认的规范往往会对equals方法进行重写,使其比较的是对象的属性值,而不是地址;
就像两个int值实现比较,我们比较的是int的值,而不关心int在内存中的物理地址,所以通常会对具有比较需求的类对象 重写equals方法。
这里的关系可以用一个Hash结构的集合的‘元素添加操作’来理解,增加一个元素时,先调用hashCode,唯一则存储,不唯一则再调用equals,结果相同则不再存储,结果不同则散列到其他位置。因为hashCode效率更高(仅为一个int值),比较起来更快。
如果不重写equals ,会出现以下情况:
两个值相同的对象,因为hashCode不一样,导致HashSet会放入值相同的对象,违背了set的初衷;
重写equals时为什么要重写hashCode ?
当equals方法被重写时,通常有必要重写hashCode方法,以维护equals方法的常规约定:
值相同的对象必须有相同的hashCode;
满足以下情况:
object1.equals(object2)为true,hashCode也相同;
hashCode不同时,object1.equals(object2)为false;
hashCode相同时,object1.equals(object2)不一定为true;
如果只重写equals,不重写hashCode ,就会出现以下情况:
两个值不同的对象的hashCode一定不一样,那么执行equals,结果为true,HashSet会放入值相同的对象,违背了set的初衷。
equals为true,但是在HashSet中却以不同的对象存储(没有重写hascode值,两个hascode值,在他看来就是两个对象)。说明必须重写hashCode()
正确重写:
重写hashCode和equals后 == hashCode equals 比较:
== 判断对象地址是否相等; hashCode 获取对象hashCode; equals 判读对象值是否相等;
如有错误,欢迎指正