Effective Java(9)equalsを上書きする場合はhashCodeを上書きする


これはずっと強調しています.
JAva仕様では、Object仕様では、同じオブジェクトのhashCodeの複数回の呼び出しを一定に保つ必要があります.オブジェクトが等しい場合はhashCodeが等しくなければなりません.逆に、オブジェクトが等しくない場合はhashCodeが等しくない必要はありません.ただし、等しくないhashCodeはハッシュリストの性能を改善します.
したがってequalsを上書きする場合はhashCodeを一緒に上書きする必要があります.そうでないと、オブジェクトがHashMapなどのhash集合に入ってから取り除かれて取れない場合があります.たとえば
public class PhoneNumber{
   private final short areaCode;
   private final short prefix;
   private final short lineNumber;

   public PhoneNumber(int areaCode, int prefix, int lineNumber){
    //...set values
   }
   @Override public boolean equals(Object o){
    if(o==this) return true;
    if(! (o instanceof PhoneNumber)) return false;
    PhoneNumber pn = (PhoneNumber)o;
    return pn.lineNumber ==lineNumber && pn.prefix == prefix && pn.areaCode==areaCode;
   }
   //No hashCode() overrided!
}

この場合:
Map<PhoneNumber, String> m = new HashMap<PhoneNumber, String>();
m.put(new PhoneNumber(707,867,5309),"Jenny");

これが呼び出された場合
m.get(new PhoneNumber(707,867,5309));
が返すオブジェクトはnullを使用します.hashCodeはputとgetメソッドのPhoneNumberに対して異なるためである.したがって、HashMapは、最初のオブジェクトをハッシュバケツに格納し、別のオブジェクトのhashCodeで別のバケツからオブジェクトを取り出します.タイムリーに一致したような2つのオブジェクトが同じバケツに分けられても,hashCodeの違いにより,直接オブジェクト等価検証に失敗する.
同時に、hashCodeが常に同じまたは極めて少量の値を返すこともできません.これにより、hashCode会keyの複数のバケツのデータ構造が劣化し、1つのhashCodeしかない超大きなバケツとなり、チェーンテーブルとなるからである.このように、このデータ構造のクエリ効率は、いくつかの大きなhashセットにとって、パフォーマンスに影響を与え、プログラムが使用できなくなることもあります.
本ではhashCode生成のパターンをいくつか紹介した.よく分からないが、hashCodeの実現は工学の問題だけでなく、数学の問題でもあり、水は深くなるようだ.本人はapacheのHashCodeBuilderをよく使ってhashCodeの生成を完了していると言っています.
@Override
public int hashCode() {  
 return new HashCodeBuilder(13, 31).append(this.id) .append(this.fieldA).append(this.fieldB).toHashCode();  
}  
便利で使いやすいです.