3 回答
TA贡献1835条经验 获得超7个赞
以下是我在阅读 Effective Java 2nd Edition 时的笔记:
Equals 必须遵守一般合同:
反身的:对于
non-null x
:x.equals(x) == true
对称:对于
non-null x,y
:x.equals(y) <==> y.equals(x)
传递:对于
non-null x,y,z
:x.equals(y) and y.equals(z) ==> x.equals(z) == true
一致:对于任何非空 x,y: if
x.equals(y) == true
,如果x
和y
空:对于非空
x
:x.equals(null) == false
高质量等于方法:
使用 == 检查参数是否是对该对象的引用 (
x == x
)使用 instanceof 检查参数是否是正确的类型(也检查
null
)将参数转换为正确的类型
对于类中的每个“重要”字段,检查参数的该字段是否与该对象的相应字段匹配
完成后,检查是否对称、传递和一致
最后的警告:
覆盖 equals 时始终覆盖 hashCode
不要试图太聪明
不要在 equals 声明中用其他类型替换 Object -> 不值得为了增加复杂性而获得轻微的性能提升
来自 Effective Java 2nd Edition 的Hashcode直接引用
在名为 result 的 int 变量中存储一些常量非零值,例如 17。
对于
f
对象中的每个重要字段(即 equals 方法考虑的每个字段),请执行以下操作:计算字段的 int 哈希码 c:
将步骤 2.a 中计算的哈希码 c 合并到结果中,如下所示:
result = 31 * result + c;
如果该字段是布尔值,则计算
(f ? 1 : 0)
.如果该字段是
byte, char, short, or int, compute (int) f.
如果该字段是
long, compute (int) (f ^ (f >>> 32)).
如果该字段是
float, compute Float.floatToIntBits(f).
如果字段是 a
double, compute Double.doubleToLongBits(f)
,则对结果进行哈希处理long
。如果该字段是对象引用并且此类的 equals 方法通过递归调用比较该字段,则在该字段上
equals
递归调用hashCode
。如果需要更复杂的比较,请为此字段计算“规范表示”并在规范表示上调用 hashCode。如果字段的值为null
,return 0
(或其他一些常数,但 0 是传统的)。如果该字段是一个数组,则将其视为每个元素都是一个单独的字段。也就是说,通过递归应用这些规则来计算每个重要元素的哈希码,并在步骤 2.b 中组合这些值。如果数组字段中的每个元素都很重要,则可以使用 1.5 版中添加的 Arrays.hashCode 方法之一。
返回结果。
当你写完 hashCode 方法后,问问自己相等的实例是否有相等的哈希码。编写单元测试来验证你的直觉!
所以遵循这些规则:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Employee)) {
return false;
}
Employee other = (Employee) obj;
return super.equals(other) &&
Double.compare(this.salary, other.salary) == 0 &&
this.hireDay.equals(other.hireDay);
}
在您的情况下,虽然它似乎id应该已经唯一地标识任何人,所以您应该只使用它进行比较,而不是在任何子类中覆盖它。
TA贡献1951条经验 获得超3个赞
如果你想实现 equals 和 hashcode 方法使用 eclipse 只需右键单击文件转到源并选择 generate equals() & hashcode() 和你需要的字段,如下所示:
TA贡献1757条经验 获得超8个赞
两个人有没有可能永远一样id
?它不应该。所以逻辑延伸到Employee
类,这意味着在类中实现equals
和就足够了。hashCode
Person
此时,由于您只处理一个int
,您可以使用Integer.hashCode(id)
forhashCode
并仅比较 的值equals
。
添加回答
举报