Effective Java(9)equalsを上書きする場合はhashCodeを上書きする
これはずっと強調しています.
JAva仕様では、Object仕様では、同じオブジェクトのhashCodeの複数回の呼び出しを一定に保つ必要があります.オブジェクトが等しい場合はhashCodeが等しくなければなりません.逆に、オブジェクトが等しくない場合はhashCodeが等しくない必要はありません.ただし、等しくないhashCodeはハッシュリストの性能を改善します.
したがってequalsを上書きする場合はhashCodeを一緒に上書きする必要があります.そうでないと、オブジェクトがHashMapなどのhash集合に入ってから取り除かれて取れない場合があります.たとえば
この場合:
これが呼び出された場合
同時に、hashCodeが常に同じまたは極めて少量の値を返すこともできません.これにより、hashCode会keyの複数のバケツのデータ構造が劣化し、1つのhashCodeしかない超大きなバケツとなり、チェーンテーブルとなるからである.このように、このデータ構造のクエリ効率は、いくつかの大きなhashセットにとって、パフォーマンスに影響を与え、プログラムが使用できなくなることもあります.
本ではhashCode生成のパターンをいくつか紹介した.よく分からないが、hashCodeの実現は工学の問題だけでなく、数学の問題でもあり、水は深くなるようだ.本人はapacheのHashCodeBuilderをよく使って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();
}
便利で使いやすいです.