Java 的 equal 和 hashcode 是相亲相爱的一对
请看一下这单身狗的待遇吧,男单身狗的待遇。
public class EqualTest { private String Odd, even; public EqualTest(String Odd, String even) { this.Odd = Odd; this.even = even; } public boolean equals(Object o) { if (!(o instanceof EqualTest)) return false; EqualTest n = (EqualTest)o; return n.Odd.equals(Odd) && n.even.equals(even); } /* public int hashCode() { return 32 * Odd.hashCode() + even.hashCode(); } */ public static void main(String[] args) { Set<EqualTest> s = new HashSet<>(); s.add(new EqualTest("sigle", "couple")); System.out.println(s.contains(new EqualTest("sigle", "couple"))); } } // 输出 false
女单身狗待遇:
public class EqualTest { private String Odd, even; public EqualTest(String Odd, String even) { this.Odd = Odd; this.even = even; } /* public boolean equals(Object o) { if (!(o instanceof EqualTest)) return false; EqualTest n = (EqualTest)o; return n.Odd.equals(Odd) && n.even.equals(even); } */ public int hashCode() { return 32 * Odd.hashCode() + even.hashCode(); } public static void main(String[] args) { Set<EqualTest> s = new HashSet<>(); s.add(new EqualTest("sigle", "couple")); System.out.println(s.contains(new EqualTest("sigle", "couple"))); } } // 输出 false
虐狗一对出现:
public class EqualTest { private String Odd, even; public EqualTest(String Odd, String even) { this.Odd = Odd; this.even = even; } public boolean equals(Object o) { if (!(o instanceof EqualTest)) return false; EqualTest n = (EqualTest)o; return n.Odd.equals(Odd) && n.even.equals(even); } public int hashCode() { return 32 * Odd.hashCode() + even.hashCode(); } public static void main(String[] args) { Set<EqualTest> s = new HashSet<>(); s.add(new EqualTest("sigle", "couple")); System.out.println(s.contains(new EqualTest("sigle", "couple"))); } } // 输出 true
追根究底
hashcod约定
When overriding equals() in a class, the hashCode() method should be overrided as well such that it maintains its contract with equals().
简单说:hashCode 约定要求相等的对象要具有相同的散列码。为了遵守这项约定,无论何时,只要你覆写了equals 方法,你就必须同时覆写 hashCode 方法。
简单来说如果两个对象equals相等,则它们的hashcode必须相等,而hashcode相等,equals则不一定相等。原因在于,前面我们说过hashCode是尽量保证唯一,尽量平均分布,但由于不可避免地会存在哈希值冲突的情况,此时两个对象即便hashCode相等,equals也不一定相等,而equals相等hashCode必定相等是因为,对象的内容相等而根据对象内容生成的hashCode当然也是相等的了。