以下のコードでは、ハッシュコードは常に同じです。なんでそんなの?
コード:
public class BooleanClass {
public static void main(String[] args) {
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(false);
Boolean b3 = new Boolean(true);
Boolean b4 = new Boolean(false);
Boolean b5 = new Boolean(false);
Boolean b6 = new Boolean(true);
System.out.println(b1.hashCode());
System.out.println(b2.hashCode());
System.out.println(b3.hashCode());
System.out.println(b4.hashCode());
System.out.println(b5.hashCode());
System.out.println(b6.hashCode());
}
}
出力:
1231
1237
1231
1237
1237
1231
常に同じ番号1231
および1237
が印刷されます。何らかの理由?
JavaDocBoolean.hashCode()
メソッドの説明:
整数を返します
1231
このオブジェクトがtrue
を表す場合;整数を返します1237
このオブジェクトがfalse
を表す場合。
HashCode()のコントラクトは次のとおりです。
equals(Object)
メソッドに従って2つのオブジェクトが等しい場合、2つのオブジェクトのそれぞれでhashCode()
メソッドを呼び出すと、同じ整数の結果が生成される必要があります。
ブール値にはtrue
とfalse
の2つの値しかありませんが、取得できるハッシュコードは2つだけです。
ブールクラスから直接:
public int hashCode()
{
return ((this.value) ? 1231 : 1237);
}
これは、ブール型のハッシュコードを生成するメソッドです。そのため、trueまたはfalseに対して常に同じハッシュコードを取得します。
これはブール値のコンストラクターです
public Boolean(boolean paramBoolean)
{
this.value = paramBoolean;
}
したがって、this.valueはtrueまたはfalseのいずれかになり、trueの場合は1231になり、falseの場合は1237になります。
ハッシュ関数のポイントは、任意の長さのデータを固定長のデータにマップすることです。ハッシュ関数によって返される値は、ハッシュ値、ハッシュコード、ハッシュサム、チェックサム、または単にハッシュと呼ばれます。入力が同じであれば、ハッシュ関数は常にまったく同じハッシュを返します。したがって、ハッシュtrue
は常に1231
に等しく、ハッシュfalse
は常に1237
に等しくなります。
値ではなくインスタンスを本当に区別する必要がある場合(これは実際に必要なことはめったにありませんが、たまに発生します)、 IdentityHashMap
を参照してください。
(基本的に、IdentityHashMap
はオブジェクトの「実際の」クラスの.equals()
と.hashcode()
の両方の実装をバイパスし、Object
の実装を使用します。)
その質問がなぜそれほど注目を集めたのか理解できません。そうでなければびっくりします。他の人からも指摘されていたので、 documentation でも指定されています。
ただし、ドキュメントがない場合でも、理由は簡単に理解できます。ハッシュ関数の定義を確認するだけです function 。
ハッシュ関数は、任意の長さのデータを固定長のデータにマップする任意のアルゴリズムです。
そして 数学的な定義 からmapは関数です。つまり、同じ値が常に同じ値を生成します。
これで問題が解決しない場合は、次の例をご覧ください。
int a = 400;
int b = 400;
ハッシュが異なることを期待する必要がありますか?おそらくありません。では、真と偽の場合、なぜそれらが異なる必要があるのでしょうか。