equals 方法
equals
方法需要满足的规范:
- 自反性: 对于任意非空引用 x,
x.equals(x)
应该返回true
; - 对称性: 对于任意引用, 当且仅当
x.equals(y) == true
时,y.equals(x) == true
; - 传递性: 对于任意引用 x/y/z, 如果
x.equals(y) == true
和y.equals(z) == true
, 则x.equals(z) == true
; - 对于任意非空引用 x,
x.equals(null) == false
;
编写 equals()
方法的建议:
- 添加
@Override
注解, 重载父类Object.equals(Object)
方法; - 参数为
Object otherObject
, 稍后需要将它转换成另一个叫做other
的变量; - 检测
this
与otherObject
是否引用同一个对象; - 检测
otherObject
是否为null
, 如果为null
, 返回false
; - 比较
this
与otherObject
是否属于同一个类.
如果equals
的语义在每个子类中有所改变, 那就要使用getClass
检测; - 将
otherObject
转换为响应的类型变量other
; - 对所有需要比较的域进行比较, 使用
==
比较基本类型域, 使用equals
比较对象域. 如果所有的域都匹配, 就返回true
, 否则返回false
; - 如果在子类中重新定义了
equals
, 就要在其中调用super.equals(otherObject)
, 如果返回ture
, 则继续比较子类特有的域.
在比较两个对象是否相等时, 可使用 Objects.equals()
方法.
例如对于 Objects.equals(a, b)
:
- 当两个参数都为 null 时, 返回
ture
; - 当其中一个参数为 null 时, 返回
false
; - 当两个参数都不为 null 时, 返回
a.equals(b)
的返回值.
hashCode 方法
如果重新定义了 equals
方法, 就必须重新定义 hashCode
方法, 以便用户将对象插入到散列表中.
hashCode
方法应该返回一个整型数值(也可以是负数), 并合理地组织实例域的散列码, 以便能够让哥哥不同的对象产生的散列码更加均匀.
Objects.hash(Object.. value)
可以传递多个参数并据此产生序列码.
示例代码:
import java.util.Objects;
public class TestEqualsAndHashCode {
private Object obj;
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
@Override
public boolean equals(Object otherObject) {
if (this == otherObject) {
return true;
}
if (null == otherObject) {
return false;
}
if (getClass() != otherObject.getClass()) {
return false;
}
TestEqualsAndHashCode other = (TestEqualsAndHashCode) otherObject;
return Objects.equals(getObj(), other.getObj());
}
@Override
public int hashCode() {
return Objects.hash(obj);
}
public static void main(String[] args) {
TestEqualsAndHashCode a = new TestEqualsAndHashCode();
TestEqualsAndHashCode b = new TestEqualsAndHashCode();
a.setObj(1);
b.setObj(1);
System.out.println(Objects.equals(a, b));
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}