hashCode()メソッドのオーバーライドはequals()のオーバーライドと密接に関連しており、両方のメソッドがHashMap、HashSet、Hashtableなど、比較とハッシュ関数に基づくコレクションでのオブジェクトの正しい使用に必要な基盤を形成します。
規則:
class User { private String name; public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof User)) return false; User user = (User) o; return Objects.equals(name, user.name); } public int hashCode() { return Objects.hash(name); } }
質問: 「equals()が異なる二つのオブジェクトが同じhashCode()を返した場合、これはエラーになるのでしょうか?」
答え: いいえ、これはエラーではありません。ハッシュコードの衝突は解決可能で予想されるもので、重要なのはequalsで等しいオブジェクトが同じhashCodeを持つことです。equalsで異なるオブジェクトが同じhashCodeを持つ場合、コレクションは遅くなります(衝突が増えるため)が、正しく動作します。
物語
財務ソフトウェアでは、プロジェクトを複数のフィールドで比較していますが、equals()だけをオーバーライドしました。HashSetにオブジェクトを格納していたため、hashCode()がオーバーライドされず、デフォルトで動作していたため、重複が発生しました。
物語
倉庫管理システムでは、ビジネスロジックの変更を追加した後、equals()を拡張しましたが、hashCode()を更新するのを忘れました。異なるhashCodeを持つがequals=trueのオブジェクトがHashMapで失われ(キーで見つからない)、大きな財務上のエラーを引き起こしました。
物語
ウェブアプリケーションでは、hashCodeの計算に可変フィールドを使用していました。内部フィールドの値が更新されるとハッシュが変更され、オブジェクトはHashSet/HashMapで「失われ」ました:標準的なメソッドで見つけたり削除したりすることができず、メモリリークやバグを引き起こしました。