独自のキーペアオブジェクトを作成するときは、いくつかの問題に直面する必要があります。
まず、との実装に注意する必要がhashCode()
ありequals()
ます。これを行う必要があります。
次に、実装するときはhashCode()
、それがどのように機能するかを理解していることを確認してください。与えられたユーザー例
public int hashCode() {
return this.x ^ this.y;
}
実際には、実行できる最悪の実装の1つです。理由は単純です。同じハッシュがたくさんあります。そして、hashCode()
はまれで、最高の状態で一意である傾向があるint値を返す必要があります。次のようなものを使用します。
public int hashCode() {
return (X << 16) + Y;
}
これは高速で、-2 ^ 16〜2 ^ 16-1(-65536〜65535)のキーに対して一意のハッシュを返します。これはほとんどの場合に当てはまります。ごくまれに、この範囲を超えています。
第三に、実装するときequals()
は、キーがオブジェクトであるため、それが何に使用されるかを理解し、キーの作成方法に注意してください。多くの場合、ステートメントが原因で常に同じ結果が得られる場合は、不要です。
このようなキーを作成する場合:キーmap.put(new Key(x,y),V);
の参照を比較することは決してありません。マップにアクセスするたびに、のようなことをしますmap.get(new Key(x,y));
。したがって、equals()
のようなステートメントは必要ありませんif (this == obj)
。それは決して起こりません。
if (getClass() != obj.getClass())
あなたのequals()
より良い使用の代わりにif (!(obj instanceof this))
。サブクラスでも有効です。
したがって、比較する必要があるのは実際にはXとYだけです。したがって、equals()
この場合の最適な実装は次のようになります。
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
したがって、最終的に、キークラスは次のようになります。
public class Key {
public final int X;
public final int Y;
public Key(final int X, final int Y) {
this.X = X;
this.Y = Y;
}
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
public int hashCode() {
return (X << 16) + Y;
}
}
ディメンションインデックスX
とY
パブリックアクセスレベルは最終的なものであり、機密情報が含まれていないため、これらを指定できます。にキャストするときに、アクセスレベルがどのような場合でも正しくprivate
機能するかどうかは、100%わかりません。Object
Key
ファイナルについて疑問がある場合は、インスタンス化時に設定され、変更されない値をファイナルとして宣言します。したがって、オブジェクト定数です。