什么问题/陷阱,必须重写时,必须考虑equals和hashCode?
equals
hashCode
理论(针对语言律师和数学倾向者): equals()(javadoc)必须定义一个等价关系(它必须是自反的,对称的和可传递的)。另外,它必须是一致的(如果未修改对象,则它必须保持返回相同的值)。此外,o.equals(null)必须始终返回false。
equals()(javadoc)
o.equals(null)
false
hashCode()(javadoc)也必须是一致的(如果未根据修改对象equals(),则它必须保持返回相同的值)。
hashCode()(javadoc)
该关系的两种方法之间是:
每当a.equals(b),则a.hashCode()必须与相同b.hashCode()。
在实践中: 如果覆盖一个,则应覆盖另一个。
使用用于计算的相同字段集equals()进行计算hashCode()。
equals()
hashCode()
使用优秀的辅助类EqualsBuilder和HashCodeBuilder从阿帕奇共享郎库。一个例子:
EqualsBuilder
HashCodeBuilder
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()永远不会在对象位于集合中时改变。确保这一点的防弹方法是使您的钥匙不可变,这还有其他好处。