equals覆盖和时必须考虑哪些问题/陷阱hashCode?
equals
hashCode
equals()( javadoc ) 必须定义一个等价关系(它必须是 自反 的、 对称 的和 传递 的)。此外,它必须是 一致 的(如果对象没有被修改,那么它必须保持返回相同的值)。此外,o.equals(null)必须始终返回 false。
equals()
o.equals(null)
hashCode()( javadoc ) 也必须是 一致 的(如果对象没有被 修改equals(),它必须保持返回相同的值)。
hashCode()
这两种方法之间的 关系是:
无论何时a.equals(b),则a.hashCode()必须与 相同b.hashCode()。
a.equals(b)
a.hashCode()
b.hashCode()
如果你覆盖一个,那么你应该覆盖另一个。
使用与计算相同的一组字段equals()来计算hashCode()。
使用Apache Commons Lang库中出色的帮助类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(); } }
当使用基于散列的集合或映射时,例如HashSet、LinkedHashSet、HashMap、Hashtable或WeakHashMap,请确保您放入集合中的关键对象的 hashCode() 在对象位于集合中时不会更改。确保这一点的万无一失的方法是使您的密钥不可变,这还有其他好处。