デフォルトの実装については、こちらを参照してください:
http://msdn.microsoft.com/en-us/library/system.object.gethashcode.aspx
GetHashCode メソッドの既定の実装では、異なるオブジェクトに対して一意の戻り値が保証されるわけではありません。さらに、.NET Framework は GetHashCode メソッドの既定の実装を保証しておらず、返される値は .NET Framework の異なるバージョン間で同じになります。したがって、このメソッドのデフォルトの実装は、ハッシュ目的で一意のオブジェクト識別子として使用しないでください。
しかし、皆さんが本当に知りたいと思うのは、ハッシュ コードがどのように機能するかということです。
次のクラスがあるとします。
public Person
{
private string name;
public Person(Name name)
{
this.name = name;
}
}
では、2 人の人物を比較して、同じ名前かどうかを確認したいとします。これはどのように行うのでしょうか? Object に実装されている equals をオーバーライドします。(C# のすべてのクラスは Object を暗黙的に継承します) 以下のように:
public Person
{
private string name;
public Person(Name name)
{
this.name = name;
}
public override bool Equals(Object obj)
{
if(obj == null)
return false // not equal if obj is null
Equals temp = obj as Equals; // temp set to null if obj can not be cast to equals
if(p == null)
return false
// if code gets here, the code object passed is an instance of Equals.
// Now we have to check if the strings match.
bool isEqual = p.name == this.name; // set if the two names match
return isEqual; // return if these two match
}
}
これで、2 人が等しいかどうかを確認できます。例:
Person p1 = new Person("Jack");
Person p2 = new Person("Jack");
Person p3 = new Person("Jill");
Object p4 = new Person("Jill");
p1.Equals(p2) // returns true
p1.Equals(p3) // returns false
p4.Equals(p1) // returns false
p4.Equals(p3) // returns true
"amy"
ここで、100 万人のような膨大な人のリストがあり、その名前の人物がこのリストに存在するかどうかを知りたいとしましょう。どうやってこの人を見つけますか?すべての名前を 1 つずつループして、その Person が amy と等しいかどうかを確認しますか? しかし、それは非常に遅いでしょう.エイミーがこのリストの100万人目の人物だったらどうなるでしょうか? どうすればパフォーマンスを改善できますか?
ハッシュコードを入力します。
簡単なハッシュコード アルゴリズムを作成するとします。ハッシュコードは、人物名の各文字の各数字の合計です。
public Person
{
private string name;
public Person(Name name)
{
this.name = name;
}
public override bool Equals(Object obj)
{
if(obj == null)
return false // not equal if obj is null
Equals temp = obj as Equals; // temp set to null if obj can not be cast to equals
if(p == null)
return false
// if code gets here, the code object passed is an instance of Equals.
// Now we have to check if the strings match.
bool isEqual = p.name == this.name; // set if the two names match
return isEqual; // return if these two match
}
public override int GetHashCode()
{
int sum = 0;
foreach(char c in this.name)
{
sum += c;
}
return sum;
}
}
したがって、amy
彼女のハッシュコードがあれば1 + 13 + 25
、そう38
です。
通常のリストの代わりに、いわゆる「バケット」を含むリストがあります。ハッシュコードによって、どのバケットに移動するかが決まります。彼女がバケツにamy
入った場合、ハスコードを持っています。38
38
ここで、名前に別の人物がいるとしましょう。may
彼女の名前には同じ文字が含まれているため、ハッシュコードもであり38
、彼女もバケットに入ります38
さて、エイミーがこのリストに存在するかどうかを確認したいときはいつでも。最初に彼女のハッシュコードをチェックします。38
今度はバケット 38 を調べ、バケット内のすべてのオブジェクトをループして、バケット内38
のオブジェクトのいずれかが38
amy と一致するかどうかを確認します。true の場合は true を返し、false の場合は false を返します。したがって、100 万人の人物がいる場合、このリストに存在するかどうかを知るために行う必要があるチェックのamy
リストは大幅に削減されます。
したがって、基本的に、ハッシュコードを使用する場合は、次の規則に従う必要があります。
- ハッシュコードを使用する場合は、equals をオーバーライドして実装する必要があります。
- Equals が true を返す 2 つのオブジェクトの場合、それらは常に同じハッシュコードを持っている必要があります
- 異なる 2 つのオブジェクトが同じハッシュコードを持つ場合がありますが、必ずしも同じである必要はありません。
それが基本的にその要点です。