Java--equals和 == 的比较和equals()、HashCode()的重写

原文:https://www.e-learn.cn/content/java/1078244

一、 equals和 == 的比较
1、== 运算符
① == 如果比较的是基本数据类型,则比较的是值。
② == 如果比较的是引用数据类型,则比较的是地址值。
2、equals
①它属于java.lang.Object类里面的方法,如果该方法没有被重写则等同于==。
②public boolean equals(Object obj),用于比较两个对象[即引用数据类型]是否相等。
注意:在使用中String的equals方法看似比较的值,其实是String重写了equals方法。

二、 ==、equals、HashSet的使用
案例:
Java--equals和 == 的比较和equals()、HashCode()的重写
1、==比较的是new出来的对象,因此比较的是地址值,所以比较结果是false
2、a.equals(a2)调用的是String的equals()方法,由于String重写了equals的方法,所以这里比较的是值。
Java--equals和 == 的比较和equals()、HashCode()的重写
3、HashSet其实就是HashMap,HashMap其实就是比较的key的hashcode值,存入的values是常量值。
String重写了equals因此有相同的hashcode码,所以对hashSet就是一个值。会覆盖存储!
Java--equals和 == 的比较和equals()、HashCode()的重写
Java--equals和 == 的比较和equals()、HashCode()的重写
Java--equals和 == 的比较和equals()、HashCode()的重写
4、对于Person类没有重写equals()方法则,继承了Object的equals方法,比较的是地址值,所以new出来的是两个不同的对象,具有不同的hashcode码,HashSet的size值为2。16进制地址值不同。
Java--equals和 == 的比较和equals()、HashCode()的重写

三、 重写equals()方法时要重写HashCode()方法,31的含义?
1.在重写equals方法的类中,必须重写hashCode方法,如果不重写的话就会违反Object和hashCode的通用约定,导致无法结合所有基于散列码的集合一起正常运作,例如:HashMap、HashSet、HashTable。当一个类有自己特有的逻辑相等的概念,一个类的equals放发改写后,两个截然不同的实例,可能在逻辑上是相等的,根据Object.hashCode()方法,它们仅仅是两个对象。
违反了:相等的对象必须具有相等散列码。
因此:重写equals()时需要同时重写hashCode()方法。
2.hashCode中31的选取理由
①减少hash冲突,31是一个奇素数
②任何数a*31就可以被JVM优化为(a<<5)-a,移位和减法的效率要比乘法操作效率高的多,对于左移虚拟机中有相关优化。并且31只占用5bits。

四、 equals()和hashCode()重写
1.equals的重写步骤
①地址值相等,是同一个对象,是其本身
②判断是不是【所用对象】类型的对象
③比较需要比较的字段,string类型用equals,基本数据类型用==即可,如果是多个值进行比较,则用&&符号连接
Java--equals和 == 的比较和equals()、HashCode()的重写
2.hashCode的重写
Java--equals和 == 的比较和equals()、HashCode()的重写
Java--equals和 == 的比较和equals()、HashCode()的重写
重写之后的结果:
Java--equals和 == 的比较和equals()、HashCode()的重写
注意:如果不重写hashcode()会有地址值一致,hashcode的值不一致的情况,就是逻辑相等的情况,其实hashCode码不一样。