equals理解
一. equals与"=="的区别理解
equals对比字段,"=="对比地址-->no这不准确
object.equals()的底层原理就是通过"=="进行对比],String等类重写了Object的equals方法和hashcode.
对于我们传统的equals与==要分类型:
- 基本数据类型,也称原始数据类型。
byte,short,char,int,long,float,double,boolean,他们之间的比较,应用双等号(==),比较的是他们的值。
- 复合数据类型。
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。
JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地址。
但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于复合数据类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。
二. 为什么重写equals的同时还要重写hashcode
这是一个默认的约定,当两个对象equals的结果为true时,他们的hashcode的一定相等,并且在很多地方为了提高性能也使用hashCode进行判断,比如hushSet(不可重复,根据hashCode判断),在框架中可能也有应用.反过来,两个对象的hashcode值相等,equals的结果未必为true,这个关系是单向的.[离散数学辩证,另,hashcode是本地方法,它的实现是根据本地机器相关的,采用的算法的问题,有可能导致两个不同对象的hashCode相同]
三. 如何实现重写的hashcode与对比目标相同
定义:
hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值。public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
—>
它是根据对象的地址或者字符串或者数字算出来的
四. 具体算法
1. 重写某一个不带内部类声明的对象时的equals和hashcode代码
@Override
public boolean equals(Object o) {
<!-- 如果对象地址相等直接返回true -->
if (this == o) return true;
<!-- 如果对象为空或者类型不一致直接为false -->
if (o == null || getClass() != o.getClass()) return false;
<!-- 创建了个对象进行对比 -->
CloneTest2 that = (CloneTest2) o;
<!-- 分别对成员进行对比这里不带that的name是当前类的全局变量 -->
return Objects.equals(name, that.name) && Objects.equals(age, that.age) && Objects.equals(address, that.address);
}
<!-- 重写hashcode -->
@Override
public int hashCode() {
<!-- 把要对比的成员变量给到下面这个方法 -->
return Objects.hash(name, age, address);
}
2. Objects.equals的代码
<!-- Objects.equals的代码,这里相当于再一次回调了equals方法去但是只对成员类型这个基本类型进行对比,也就是直接等同于多次"=="判断 -->
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
3. 重写的Objects.hash(name, age, address);源代码
public static int hash(Object... values) {
<!-- 把这些成员放到数组里头生成hashcode -->
return Arrays.hashCode(values);
}
4. Arrays.hashCode(values);源代码
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
<!-- element.hashCode())这个是native本地方法,与本地机器相关 -->
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}