(equals
を介して)2つの等しいオブジェクトに同じハッシュコードを提供することが重要である理由を理解しています。しかし、その逆も同様です。2つのオブジェクトが同じハッシュコードを持っている場合、それらは等しい必要がありますか?契約はまだ成立していますか? equalsメソッドに参加しているすべての属性がハッシュコードメソッドのオーバーライドにも使用されている場合は、常に同じオブジェクトのハッシュコードが使用されるため、これが発生する可能性のある例を見つけることができません。コメントしてください。
2つのオブジェクトが同じhashcode
を持っている場合、それらは必ずしも等しいとは限りません。そうでなければ、完璧なハッシュ関数を発見するでしょう。
しかし、反対のことが当てはまります。オブジェクトが等しい場合、それらは同じhashcode
でなければなりません。
hashCode
関数の目的は、オブジェクトを、自分のセットの外にあるすべてのアイテムと等しくないことがわかっているもののセットにすばやく分割できるようにすることです。 1つに1,000個のアイテムがあり、それらをほぼ同じサイズの10個のセットに分割するとします。 hashCode
を1回呼び出すと、これらのアイテムでequals
を使用しなくても、アイテムが900と等しくないことがすぐにわかります。アイテムを他の100アイテムと比較するためにequals
を使用する必要があったとしても、それをすべての1000アイテムと比較するコストの1/10にすぎません。実際には、大規模なコレクションであっても、hashCode
は99.9%以上の不平等なアイテムを排除することが多く、調査する必要があるのはほんの一握りです。
次のJavadocによると: http://download.Oracle.com/javase/6/docs/api/Java/lang/Object.html#hashCode%28%29
Equals(Java.lang.Object)メソッドに従って2つのオブジェクトが等しくない場合、2つのオブジェクトのそれぞれでhashCodeメソッドを呼び出すと、異なる整数の結果が生成される必要はありません。ただし、プログラマは、異なるオブジェクトに対して異なる整数の結果を生成すると、ハッシュテーブルのパフォーマンスが向上する可能性があることに注意する必要があります。
編集:現実の世界では、2つの文字列が同じハッシュコードを持つ場合があります。たとえば、長さが10の小文字の英字( "aaaaaaaaaa"、 "aaaaaaaaab"など)を含むすべての文字列の組み合わせを保存する場合、141.167.095.653のそれぞれに一意のハッシュコードを割り当てることはできません。 Javaのintは32ビットであるため、最大4.294.967.296の異なる値を持つことができるため、376の組み合わせ。
実際のところ
public int hashCode(){
return 1;
}
有効なハッシュコードの実装ですが、ひどいものです。すべてのハッシュテーブルを遅くします。しかし、はい、同じハッシュコードで2つの異なるオブジェクトを持つことができます。しかし、それは一般的なケースではありません。実際の実装では、ほとんどの場合、異なる値に対して異なるハッシュコードを与える必要があります。
奇妙なことに、NumberFormatは、次の推奨事項に違反するJava Foundationクラスの例です。
合理的に実用的である限り、クラスObjectによって定義されたhashCodeメソッドは、個別のオブジェクトに対して個別の整数を返します。
これは、少なくともJavaのバージョンの下で、現在Mac OS X 10.6で実行している場合)を示すコードです。
Numberformat nf = NumberFormat.getNumberInstance();
NumberFormat nf2 = NumberFormat.getNumberInstance();
assert nf != nf2; // passes -- they are different objects
assert !nf.equals(nf2); // passes -- they are not equal
assert nf.hashCode() != nf2.hashCode(); // fails -- same hash code
hashCode
値は実装によって異なります。たとえば、String
クラスは、値に応じてhashCode()
関数を実装します。その意味は
String a=new String("b");
String b=new String("b");
hashcode
は同じですが、これらは2つの異なるオブジェクトです。およびa==b
はfalse
を返します。
証明するには、2つのオブジェクトが同じhashCodeを持っている場合、それらが等しいことを意味するわけではありません
2つのユーザー定義クラスがあるとします
class Object1{
private final int hashCode = 21;
public int hashCode(){
return hashCode;
}
public boolean equals(Object obj) {
return (this == obj);
}
}
class Object2{
private final int hashCode = 21;
public int hashCode(){
return hashCode;
}
public boolean equals(Object obj) {
return (this == obj);
}
}
Object1 object1 = new Object1();
Object2 object2 = new Object2();
Object1 object3 = new Object1();
if(object1.hashCode() == object2.hashCode()){
// return true, because the hashcodes are same
}
but
if(object1.equals(object3)){
// will fail, because two different objects
}
hashcode()は、オブジェクトごとに一意の整数IDを返します。オブジェクトのハッシュコードが別のオブジェクトのハッシュコードと同じでない場合、equals()メソッドを実行する理由はありません。2つのオブジェクトが同じではないことがわかっているだけです。一方、ハッシュコードが同じ場合は、equals()メソッドを実行して、値とフィールドが同じかどうかを判断する必要があります。
ハッシュコードメソッドは整数を返します。整数の範囲が終了すると、2つの異なるオブジェクトも同じハッシュコードを持ちます。したがって、2つの異なるオブジェクトが同じハッシュコードを持っている必要はありません。