死磕Java之hashcode与equals方法
hashCode方法与equals方法来源于Java最基本的类Object,这两个方法常用于自定义类在Java集合类中,类对象的判断等;掌握理解该方法是程序员必备技能。
01
hashCode
首先让我们先来了解hash的概念。
hash:就是把任意长度的输入(又叫做预映射pre-image)通过散列算法变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来确定唯一的输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。
hashCode方法是基类Object类的native方法,在JDK源码中我们可以看到如下的声明:
public native int hashCode();
如果不重写该方法,默认对象的hashcode值为该对象的地址。
我们这样重写hashCode函数,如下:
public class Person { private String name; private int age; //程序猿技术 @Override public int hashCode() { if("Bob".equals(name)) return 234; return this.hashCode(); } }
为了方便,这里省略getter和setter方法,我们定义Person类,如果Person实例的名字等于Bob,那么hashcode值就一样,否则为实例地址。如果两个实例的名字一样,那么就产生了hash冲突。
我们可以把hashcode理解为人的名字,名字一样,那么人不一定是同一个人,如果两个名字相同,那么产生了冲突。
02
equals
equals方法是基类Object的实例方法,因为所有的类都有该方法。
equals方法在类Object的声明如下
public boolean equals(Object obj) { return (this == obj); }
从JDK源码看,如果不重写该方法,默认比较的是两个对象的地址。equals方法设计的初衷是为了比较内容而生,但是Object类没有属性,默认比较地址。
正确的equals方法必须满足5个特征:
1.自反性:对于任意的x,x.equals(x)结果为true。
2.对称性:对于任意的x,y,x.equals(y)的结果与y.equals(y)的结果相同。
3.传递性:对于任意的x,y,z,x.equals(y)、y.equals(x)和y.equals(z),那么一定有x.equals(z)。
4.一致性:对于任意的x,y如果比较的信息没有改变,那么无论调用多少次x.equals(y)返回的结果一定与上一次相同。
5.对于非null的x,x.equals(null)结果为false。
如果不好理解这5条,我们可以将equals比较等同于人来比较,这样是不是更好理解呢!
在重写equals方法时,内部实现分三个步骤:
1.比较引用是否相同(是否为同一对象)
2.比较类型是否一致
3.比较内容是否一致
03
hashCode与equals
equals方法与hashCode方法有一定的联系与区别,具体如下:
1.x.equals(y)为true,那么x与y的hashCode方法结果相等。
2.x.equals(x)为false,那么x与y的hashCode方法结果不一定相等。
我们这里可以那上面的对比作为理解,两个人是同一个人,那么他们的名字就相同,如果两个人不是同一个人,名字有可能不同,也有可能相同!
点击上方蓝色字体,关注我们
15