最近我通读了这个 Developer Works Document。
该文档是关于定义hashCode()和equals()有效和正确的,但是我无法弄清楚为什么我们需要覆盖这两种方法。
hashCode()
equals()
我怎样才能决定有效地实施这些方法?
Joshua Bloch 谈有效的 Java
您必须在覆盖 equals() 的每个类中覆盖 hashCode()。不这样做将导致违反 Object.hashCode() 的一般约定,这将阻止您的类与所有基于哈希的集合(包括 HashMap、HashSet 和 Hashtable)一起正常运行。
让我们尝试通过一个示例来理解它,如果我们覆盖equals()而不覆盖hashCode()并尝试使用Map.
Map
假设我们有一个像这样的类,并且MyClass如果它们相等,则两个对象importantField相等(使用eclipsehashCode()并由equals()eclipse 生成)
MyClass
importantField
public class MyClass { private final String importantField; private final String anotherField; public MyClass(final String equalField, final String anotherField) { this.importantField = equalField; this.anotherField = anotherField; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((importantField == null) ? 0 : importantField.hashCode()); return result; } @Override public boolean equals(final Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; final MyClass other = (MyClass) obj; if (importantField == null) { if (other.importantField != null) return false; } else if (!importantField.equals(other.importantField)) return false; return true; } }
想象一下你有这个
MyClass first = new MyClass("a","first"); MyClass second = new MyClass("a","second");
仅覆盖equals
equals
如果 onlyequals被覆盖,那么当您myMap.put(first,someValue)第一次调用时将散列到某个存储桶,当您调用myMap.put(second,someOtherValue)它时将散列到其他存储桶(因为它们具有不同的hashCode)。所以,虽然它们是相等的,因为它们没有散列到同一个桶,所以地图无法实现,它们都留在地图中。
myMap.put(first,someValue)
myMap.put(second,someOtherValue)
hashCode
equals()尽管如果我们 override没有必要override hashCode(),让我们看看在这种特殊情况下会发生什么,我们知道 的两个对象MyClass如果它们importantField相等但我们不 override 是相等的equals()。
仅覆盖hashCode
如果您只覆盖hashCode,那么当您调用myMap.put(first,someValue)它时,首先计算它hashCode并将其存储在给定的存储桶中。然后,当您调用它时,应该根据地图文档myMap.put(second,someOtherValue)将第一个替换为第二个,因为它们是相等的(根据业务要求)。
但问题是 equals 没有被重新定义,所以当映射散列second并遍历存储桶时,如果有一个对象k是second.equals(k)真的,它不会像second.equals(first)will be那样找到任何对象false。
second
k
second.equals(k)
second.equals(first)
false
希望很清楚