独自のキーペアオブジェクトを作成する場合、いくつかのことに直面するはずです。
まず、との実装に注意する必要が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)のキーの一意のハッシュを返します。これは、ほとんどの場合に適合します。ごくまれに、この範囲を超えています。
第3に、実装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
パブリックアクセスレベルは、最終的なものであり、機密情報が含まれていないため、与えることができます。私がいるかどうか100%わからないんだけどprivate
、アクセスレベルがで正しく動作する任意のキャスト時にケースObject
にKey
。
ファイナルについて不思議に思っている場合は、インスタンス化時に設定され、変更されない値をファイナルとして宣言します。したがって、オブジェクト定数です。