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());
}
}