web-dev-qa-db-ja.com

異なるブールインスタンスのハッシュコードが常に同じであるのはなぜですか?

以下のコードでは、ハッシュコードは常に同じです。なんでそんなの?

コード:

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が印刷されます。何らかの理由?

33
user3467951

JavaDocBoolean.hashCode()メソッドの説明:

整数を返します1231このオブジェクトがtrueを表す場合;整数を返します1237このオブジェクトがfalseを表す場合。

159
Gokul Nath KP

HashCode()のコントラクトは次のとおりです。

equals(Object)メソッドに従って2つのオブジェクトが等しい場合、2つのオブジェクトのそれぞれでhashCode()メソッドを呼び出すと、同じ整数の結果が生成される必要があります。

ブール値にはtruefalseの2つの値しかありませんが、取得できるハッシュコードは2つだけです。

51
Harmlezz

ブールクラスから直接:

 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になります。

20

ハッシュ関数のポイントは、任意の長さのデータを固定長のデータにマップすることです。ハッシュ関数によって返される値は、ハッシュ値、ハッシュコード、ハッシュサム、チェックサム、または単にハッシュと呼ばれます。入力が同じであれば、ハッシュ関数は常にまったく同じハッシュを返します。したがって、ハッシュtrueは常に1231に等しく、ハッシュfalseは常に1237に等しくなります。

11
Josh Roberts

値ではなくインスタンスを本当に区別する必要がある場合(これは実際に必要なことはめったにありませんが、たまに発生します)、 IdentityHashMap を参照してください。

(基本的に、IdentityHashMapはオブジェクトの「実際の」クラスの.equals().hashcode()の両方の実装をバイパスし、Objectの実装を使用します。)

5
keshlam

その質問がなぜそれほど注目を集めたのか理解できません。そうでなければびっくりします。他の人からも指摘されていたので、 documentation でも指定されています。

ただし、ドキュメントがない場合でも、理由は簡単に理解できます。ハッシュ関数の定義を確認するだけです function

ハッシュ関数は、任意の長さのデータを固定長のデータにマップする任意のアルゴリズムです。

そして 数学的な定義 からmapは関数です。つまり、同じ値が常に同じ値を生成します。

これで問題が解決しない場合は、次の例をご覧ください。

 int a = 400;
 int b = 400;

ハッシュが異なることを期待する必要がありますか?おそらくありません。では、真と偽の場合、なぜそれらが異なる必要があるのでしょうか。

3
Salvador Dali