This question's answers are a community effort。编辑现有答案以改善此职位。它目前不接受新的答案或互动。
覆盖
还请记住:
使用基于哈希的Collection或Map(例如HashSet,LinkedHashSet,HashMap,Hashtable或WeakHashMap)时,请确保所放置的键对象的hashCode()当对象在集合中时,进入集合的对象永远不会改变。确保这一点的防弹方法是使密钥保持不变,which has also other benefits。
覆盖
equals
和hashCode
时必须考虑哪些问题/陷阱? 最佳答案
理论(对于语言律师和数学倾向者):equals()
(javadoc)必须定义一个等价关系(它必须是自反的,对称的和可传递的)。另外,它必须是一致的(如果未修改对象,则它必须保持返回相同的值)。此外,o.equals(null)
必须始终返回false。hashCode()
(javadoc)也必须是一致的(如果未根据equals()
修改对象,则它必须保持返回相同的值)。
两种方法之间的关系为:
每当a.equals(b)
时,a.hashCode()
必须与b.hashCode()
相同。
在实践中:
如果覆盖一个,则应覆盖另一个。
使用用于计算equals()
的同一组字段来计算hashCode()
。
使用EqualsBuilder库中出色的帮助器类HashCodeBuilder和Apache Commons Lang。一个例子:
public class Person {
private String name;
private int age;
// ...
@Override
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(name).
append(age).
toHashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Person))
return false;
if (obj == this)
return true;
Person rhs = (Person) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
append(age, rhs.age).
isEquals();
}
}
还请记住:
使用基于哈希的Collection或Map(例如HashSet,LinkedHashSet,HashMap,Hashtable或WeakHashMap)时,请确保所放置的键对象的hashCode()当对象在集合中时,进入集合的对象永远不会改变。确保这一点的防弹方法是使密钥保持不变,which has also other benefits。