11

Object.hashCode() のデフォルトの動作は、a == b の場合に限り、a.hashCode() == b.hashCode() となるように、本質的にオブジェクトの「アドレス」を返すことです。スーパークラスが既に hashCode() を定義している場合、ユーザー定義クラスでこの動作を取得するにはどうすればよいですか? 例えば:

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);
  }
}

アイデア?

4

3 に答える 3

26

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

あなたはこれを書くでしょう:

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

2 つのオブジェクトが同じ場合にのみ true を返すことを equals メソッドで確認してください。そうしないと、equalsおよびhashCodeについて説明した動作が壊れます。(正確には、2 つのオブジェクトに対して異なるハッシュコードを取得した場合、equals メソッドは false を返す必要があります。) 指定された hashCode() メソッドに準拠する equals() の実装を提供するには、次のようにします。

public boolean equals(Object other){
   return this == other;
}
于 2009-06-30T13:28:36.387 に答える
9

を使用しSystem.identityHashCode()ます。使うのはこれIdentityHashMap

ただし、次の 2 つのオブジェクトである hashCode コントラクトを破る可能性があるため、既存のものをこれでオーバーライドすることには非常に注意する必要があります。hashCode()

a.equals(b) の場合、a.hashCode() は b.hashCode() と等しくなければなりません

既存の動作をオーバーライドすることでこれを壊すか、equals() もオーバーライドする必要があるかもしれません。

于 2009-06-30T13:28:55.343 に答える
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());
  }
}

次に、2 つのオブジェクトを作成します。

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

そして突然 a.equals(b) ですが、!b.equals(a) です。もちろん、より現実の世界では、A の equals() はより洗練されたものになりますが、問題は解決しません。この問題を取り除くには、常に呼び出したい

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

new equals() の先頭。

また、hashCode() のオーバーライドは equals() のオーバーライドに厳密に結び付けられているため、指定された 2 つのオブジェクトに対して super.equals() が true を返した場合、new hashCode() が super.hashCode() を返すようにする必要があります。

于 2009-07-01T13:15:44.723 に答える