2009-06-30 12 views
10

Object.hashCode()のデフォルトの動作は、a.hashCode()== b.hashCode()がa == bの場合に限り、オブジェクトの「アドレス」を実質的に返すことです。スーパークラスがすでにhashCode()を定義している場合、どのようにしてユーザー定義クラスでこの動作を取得できますか?たとえば:IDに基づくJavaハッシュコード

class A { 
    public int hashCode() { 
    return 0; 
    } 
} 

class B extends A { 
    public int hashCode() { 
    // Now I want to return a unique hashcode for each object. 
    // In pythonic terms, it'd look something like: 
    return Object.hashCode(this); 
    } 
} 

アイデア?

+1

いいえ、それはありません。 a.hashCode()!= b.hashCode()は必然的にa!= bを暗示するようにコードを取得することです。 –

+3

...しかし、a.hashCode()== b.hashCode()は、== bを意味するものではありません。 –

+1

"a.equals(b)"が必ずしも "a == b"であるとは限らない場合、ハッシュコードは等しくなければなりません: "a.hashCode()== b.hashCode()" –

答えて

25

System.identityHashCode(Object)は、この動作を提供します。

あなたはこの記述します。

class B extends A { 
    public int hashCode() { 
    return System.identityHashCode(this); 
    } 
} 

を2つのオブジェクトが同じであれば、それだけ、trueを返すこと、イコール-方法をご確認ください。さもなければ、それはequalshashCodeについて記述された振る舞いを破るでしょう。 (あなたは二つのオブジェクトごとに異なるハッシュコードを取得する場合は、正しいことには、イコール・メソッドは、falseを返すことがある。)に等しい(の実装を提供するには)与えられたのhashCode(に準拠していること) - メソッド:

public boolean equals(Object other){ 
    return this == other; 
} 
9

System.identityHashCode()を使用してください。これはIdentityHashMapの使用です。

あなたはその二つのオブジェクトであること、のhashCode契約を壊すかもしれないので、あなたは、このかかわらで既存hashCode()をオーバーライドする極めて警戒する必要があります:a.equals(b)は、その後a.hashCode(場合

) b.hashCode()と等しくなければならない

これは、既存の動作を無効にするか、equals()をオーバーライドする必要があります。

1

Mnementhが言いましたように、0(または定数値)を返すhashCode()が有効です(ラメ中)。 hashCode()は!a.equals(b)の場合にのみ、aとbの異なる値を返すことができます。
したがって、たとえば、あなたが今、あなたは二つのオブジェクト作成

class A { 
    public int hashCode() { 
    return 0; 
    } 
    public boolean equals(Object o) { 
    return o instanceof A; // all objects are equal 
    } 
} 

class B extends A { 
    public int hashCode() { 
    return System.identityHashCode(this); 
    } 
    public boolean equals(Object o) { 
    return this.hashCode().equals(o.hashCode()); 
    } 
} 

あります

A a = new A(); 
A b = new B(); 

、突然(B)をa.equalsが、b.equals(A)を!。もちろん、より現実的な生活では、Aのequals()はより洗練されたものになりますが、問題は依然として続きます。この問題を取り除くために、あなたは)(常に新しい等号の先頭に

if (super.equals(o)) return true; 

を呼びたいです。

オーバーライドするequals()に厳密に結びついているため、任意の2つのオブジェクトに対してtrueを返した場合、新しいhashCode()はsuper.hashCode()を返します。 。

関連する問題