Java编程技巧:重写hashcode 和 equals函数
在Java编程过程中,经常会需要重写hashcode和equals两个函数,本文介绍了这两个函数的作用重写这两个函数的方法。
equals函数的作用
equals函数的主要作用是判断两个对象是否相等。在这里一定要注意equals和==的区别,equals的原理是判断两个对向的
Hashcode的作用
hashcode函数的主要作用是获取哈希码,也称散列码;它的返回值实际上是一个int类型的数,这个整数的作用是确定该对象在哈希表中的索引位置,每个Java类都包含hashcode函数。
为什么要重写equals方法?
-
Object类中equals方法比较的是两个对象的引用地址,只有对象的引用地址指向同一个地址时,才认为这两个地址是相等的,否则这两个对象就不想等。
-
如果有两个对象,他们的属性是相同的,但是地址不同,这样使用equals()比较得出的结果是不相等的,而我们需要的是这两个对象相等,因此默认的equals()方法是不符合我们的要求的,这个时候我们就需要对equals()方法进行重写以满足我们的预期结果。
为什么要重写hashcode方法
- 为了维护hashCode()方法的equals协定,该协定指出:如果根据 equals()方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode方法都必须生成相同的整数结果;而两个hashCode()返回的结果相等,两个对象的equals()方法不一定相等
- HashMap对象是根据其Key的hashCode来获取对应的Value。
- 在重写父类的equals()方法时,也重写hashcode()方法,使相等的两个对象获取的HashCode值也相等,这样当此对象做Map类中的Key时,两个equals为true的对象其获取的value都是同一个,比较符合实际。
一般情况下,重写equals方法后必须重写hashcode函数。
重写equals()函数
重写equals()函数需要遵循以下规则
- 自反性:即对于任意对象x,x.equals(x)的返回值为true
- 对称性:对于任意对象x,y,如果x.equals(y) 等于true,y.equals(x)等于true
- 传递性:对于任意对象x,y,z,x.equals(y)等于true,y.equals(z)等于true,则x.equals(z)等于true
- 一致性:对于任意对象x,y ,x.equals(y)的第一次调用结果为true,则以后调用的结果都为true
- 对于非空引用x,x.equals(null)的返回值为false
重写代码如下(以实验三的飞机对象为例)
@Override
public boolean equals(Object o) {
//自反性
if (this == o) return true;
//规则五
if (o == null || getClass() != o.getClass()) return false;
//强制类型转换
Plane plane = (Plane) o;
//比较各个属性是否相等
return Objects.equals(planeNumber, plane.planeNumber) &&
Objects.equals(planeType, plane.planeType) &&
Objects.equals(seatNumber, plane.seatNumber) &&
Objects.equals(planeAge, plane.planeAge);
}
重写hashcode()函数
重写hashCode()方法需要遵循hashCode()协定:
- 一致性:在Java应用程序执行期间,在对同一对象多次调用hashCode方法时,必须一致地返回相同的整数,前提是将对象进行hashcode比较时所用的信息没有被修改。
- equals:如果根据equals()方法比较,两个对象是相等的,那么对这两个对象中的每个对象调用hashCode()方法都必须生成相同的整数结果,注:这里说的equals()方法是指Object类中未被子类重写过的equals()方法。
- 附加:如果根据equals()方法比较,两个对象不相等,那么对这两个对象中的任一对象上调用hashCode方法不一定生成不同的整数结果。但是,为不相等的对象生成不同整数结果可以提高哈希表的性能。
重写代码如下(以实验三的飞机对象为例)
@Override
public int hashCode() {
return Objects.hash(planeNumber, planeType, seatNumber, planeAge);
}