当实现这两个方法的对象被添加到集合中时,equals() 和 hashCode() 方法被证明是非常重要的。如果实施不当,它可能会搞砸你的生活。
equals(): 此方法检查作为参数传递给它的其他对象是否等于调用此方法的对象。如果你不理解合约,很容易错误地实现 equals() 方法。在重写此方法之前,以下“属性”需要记住 -
- 反身:o1.equals(o1) - 这意味着对象(例如o1)应该等于它自己
- 对称: o1.equals(o2) if and only o2.equals(o1)
- 传递:o1.equals(o2) && o2.equals(o3) 也意味着 o1.equals(o3)
- 一致:o1.equals(o2) 返回相同,只要 o1 和 o2 未修改
- null comparison : !o1.equals(null) - 这意味着任何可实例化的对象都不等于 null。因此,如果将 null 作为参数传递给对象 o1,则它应该返回 false。
- 哈希代码值: o1.equals(o2) 意味着 o1.hashCode() == o2.hashCode() .这一点非常重要。如果定义 equals() 方法,则还必须定义 hashCode() 方法。这也意味着,如果你有两个相等的对象,那么它们必须具有相同的哈希码,但反过来则不然。
来自 java 源代码
*
* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}
hashCode():此方法以整数形式返回hashCode()值,并且支持基于哈希的java.util.Collection类,如Hashtable,HashMap,HashSet等。如果一个类重写 equals() 方法,它也必须实现 hashCode() 方法。在重写此方法之前,您需要记住
- 每当在执行 Java 程序期间对同一对象多次调用 hashCode() 方法时,此方法必须始终返回相同的结果。整数结果不必从程序的一次执行到同一程序的下一次执行保持一致。
如果根据 equals() 方法,两个对象相等,则在两个对象中的每个对象中调用 hashCode() 方法必须返回相同的整数结果。因此,如果一个字段未在 equals() 中使用,则不得在 hashCode() 方法中使用。
如果根据 equals() 方法,两个对象不相等,则两个对象中的每一个都可以返回两个不同的整数结果或相同的整数结果(即,如果 2 个对象具有相同的 hashCode() 结果并不意味着它们相等,但如果两个对象相等,则它们必须返回相同的 hashCode() 结果)。
根据java源代码尽管合理实用,但 java.lang.Object 定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常是通过将对象的内部地址转换为整数来实现的)