java自定义类equal重写

前言

判断两个对象在逻辑上是否相等,有时需要根据类的某些成员变量来判断两个实例是否相等,而继承Object中的equals方法比较的只是对象的引用是否指向同一块内存地址。这时候便需要重写equals()方法了。

比较的常用对象如int,float和String等,已重写了equals和hashcode方法,默认比较的是值,而其它自定义对象在用equal时都是比较的引用地址,故此有需要的时候需要重写equal方法。

重写equal的要求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Override
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(null == obj) {
return false;
}
if (obj instanceof Test){
Test o = (Test) obj;
return this.id == o.id;
}
return false;
}

重写equals方法的要求:
1、自反性:对于任何非空引用x,x.equals(x)应该返回true。
2、对称性:对于任何引用x和y,如果x.equals(y)返回true,那么y.equals(x)也应该返回true。
3、传递性:对于任何引用x、y和z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true。
4、一致性:如果x和y引用的对象没有发生变化,那么反复调用x.equals(y)应该返回同样的结果。
5、非空性:对于任意非空引用x,x.equals(null)应该返回false。

hashCode方法也要重写

问什么说重写了equals方法都要进而重写Hashcode方法呢?

原因如下:当equals此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。如下:

(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false

  hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。

  以HashMap为例说一下的原理,HashMap存储数据的时候,是取的key值的哈希值,然后计算数组下标,采用链地址法解决冲突,然后进行存储;取数据的时候,依然是先要获取到hash值,找到数组下标,然后for遍历链表集合,进行比较是否有对应的key。比较关心的有2点:
   1.不管是put还是get的时候,都需要得到key的哈希值,去定位key的数组下标;
  2.在get的时候,需要调用equals方法比较是否有相等的key存储过。

更详细具体的可以看这篇博文或者这一篇