我应该通过调用 hashCode() 来覆盖 equals() 吗?
Should I override equals() with calls to hashCode()?
我正在编写一个具有 "Achievements" 系统的应用程序,类似于 Stack Overflow 的徽章。我也在使用 SugarORM 来存储成就的进度。这是 Achievement
class:
public class Achievement extends SugarRecord<Achievement>{
@StringRes
public int shortNameId;
@StringRes
public int descriptionId;
public int progressNow;
public int fullProgress;
//I am afraid that Sugar ORM will ignore private fields
//so I made them public. Please tell me if Sugar ORM does
//not ignore those.
}
现在我想覆盖 equals
。这很容易。
@Override
public boolean equals (Object other) {
if (other == null) return false;
if (!(other instanceof Achievement)) return false;
Achievement a = (Achievement)other;
return a.shortNameId == shortNameId &&
a.descriptionId == descriptionId &&
a.fullProgress == fullProgress;
}
然后我想起如果我覆盖equals
,我应该总是覆盖hashCode
。根据 Joshua Bloch 的 Effective Java,我这样写 hashCode
方法:
@Override
public int hashCode () {
int result = 17;
result = result * 31 + shortNameId;
result = result * 31 + descriptionId;
result = result * 31 + fullProgress;
return result;
}
然后我认为我应该将 equals
的实现更改为
@Override
public boolean equals (Object other) {
if (other == null) return false;
if (!(other instanceof Achievement)) return false;
Achievement a = (Achievement)other;
return a.hashCode() == hashCode ();
}
后来我想如果我把hashCode
覆盖错了,equals
也不行。但是,上面的实现对我来说似乎 "right",因为我认为哈希码是使对象相等的原因。
P.S。不要告诉我这是个人喜好。我认为这必须有一个标准,对吗?而且我也很愿意遵守标准。
一般来说 a.hashCode()==b.hashCode()
并不意味着 a.equals(b)
一定是真的。因此,您不应依赖 hashCode
来确定相等性。
然而,另一个方向是正确的。如果 a.equals(b)
那么 a.hashCode()
必须等于 b.hashCode()
.
我正在编写一个具有 "Achievements" 系统的应用程序,类似于 Stack Overflow 的徽章。我也在使用 SugarORM 来存储成就的进度。这是 Achievement
class:
public class Achievement extends SugarRecord<Achievement>{
@StringRes
public int shortNameId;
@StringRes
public int descriptionId;
public int progressNow;
public int fullProgress;
//I am afraid that Sugar ORM will ignore private fields
//so I made them public. Please tell me if Sugar ORM does
//not ignore those.
}
现在我想覆盖 equals
。这很容易。
@Override
public boolean equals (Object other) {
if (other == null) return false;
if (!(other instanceof Achievement)) return false;
Achievement a = (Achievement)other;
return a.shortNameId == shortNameId &&
a.descriptionId == descriptionId &&
a.fullProgress == fullProgress;
}
然后我想起如果我覆盖equals
,我应该总是覆盖hashCode
。根据 Joshua Bloch 的 Effective Java,我这样写 hashCode
方法:
@Override
public int hashCode () {
int result = 17;
result = result * 31 + shortNameId;
result = result * 31 + descriptionId;
result = result * 31 + fullProgress;
return result;
}
然后我认为我应该将 equals
的实现更改为
@Override
public boolean equals (Object other) {
if (other == null) return false;
if (!(other instanceof Achievement)) return false;
Achievement a = (Achievement)other;
return a.hashCode() == hashCode ();
}
后来我想如果我把hashCode
覆盖错了,equals
也不行。但是,上面的实现对我来说似乎 "right",因为我认为哈希码是使对象相等的原因。
P.S。不要告诉我这是个人喜好。我认为这必须有一个标准,对吗?而且我也很愿意遵守标准。
一般来说 a.hashCode()==b.hashCode()
并不意味着 a.equals(b)
一定是真的。因此,您不应依赖 hashCode
来确定相等性。
然而,另一个方向是正确的。如果 a.equals(b)
那么 a.hashCode()
必须等于 b.hashCode()
.