8

equalsメソッドは一貫しhashCodeている必要があります。つまり、2 つのオブジェクトがメソッドに従って等しい場合equals、それらのhashCodeメソッドは同じハッシュ値を返す必要があります。

hashCode() メソッドをオーバーライドしない場合、Java は一意のハッシュ コードを返します。

class HashValue {

    int x;

    public boolean equals(Object oo) {
        // if(oo instanceof Hashvalue) uncommenting ths gives error.dunno why?
        // :|
        HashValue hh = (HashValue) oo;

        if (this.x == hh.x)
            return true;
        else
            return false;
    }

    HashValue() {
        x = 11;
    }

}

class Hashing {
    public static void main(String args[]) {
        HashValue hv = new HashValue();
        HashValue hv2 = new HashValue();

        System.out.println(hv.hashCode());
        System.out.println(hv2.hashCode());

        if (hv.equals(hv2))
            System.out.println("EQUAL");
        else
            System.out.println("NOT EQUAL");
    }
}

行のコメントを外すとコンパイルエラーが発生するのはなぜですか?

オブジェクトのハッシュ コードが等しくない場合、既定のハッシュ コードが異なるのに等しいと表示されるのはなぜですか?

4

7 に答える 7

6

同等性は、メソッドequals()によってのみ決定されます。また、メソッドhashCode()は、MapやSetなどの他の状況で使用されます。これは、(効率のために)実際にequalsを呼び出す前の前提条件またはヒントのようなものです。したがって、2つのオブジェクトが等しい場合(つまり、equals()がtrueを返す場合)、それらのhashCodes()は同じ値を返す必要があると想定されます。

したがって、コードでは、hashCode()が何を実行しても、オーバーライドされたequals()がtrueを返す限り、2つのオブジェクトは等しくなります。等しいかどうかを比較するとき、hashCode()はまったく呼び出されません。

この質問には、equals()とhashCode()の関係に関するより詳細な情報があります。

于 2010-01-02T06:34:31.393 に答える
6

まず、その行を に変更する必要がありHashvalueます。HashValueこれは、クラスが実際に呼び出されているためHashValueです。

次に、行のコメントを外すと、次のようになります。

public boolean equals(Object oo) {
    if(oo instanceof HashValue)
        HashValue hh = (HashValue)oo;

    if (this.x==hh.x) {
        return true;
    } else {
        return false;
    }
}

これにはいくつか問題があります。

  1. hhこれは、最終的に使用するときにスコープ内にないため、コンパイルされません。

  2. 最初の if ステートメントは、HashValue ではない 2 つのものを比較する (つまり、例外をスローする) ときに、関数がまったく実行されないようにするか、falseHashValue が他のタイプのオブジェクトと等しくならないため、返されるようにする必要があります。false私は通常、例外をスローすることに戻ることを好みます。

  3. 条件の評価結果を返すだけなので、2 番目の if ステートメントは冗長です。

次のようにメソッドを作り直します。

public boolean equals(Object oo) {
    if(!(oo instanceof Hashvalue)) {
        return false;
    }

    HashValue hh = (HashValue)oo;
    return (this.x == hh.x);
}

これも正しくありません。すべての等しいオブジェクトが同じハッシュ コードを持つようにするには、 でオーバーライドhashCode()する必要があり、それが保証されていることを確認する必要があります。ここで、これを追加するだけです:HashValue

// inside HashValue
int hashCode() {
    return x;
}

あなたのオブジェクトは単なるラッパーであるため、実装は簡単ですint。オブジェクトがより洗練されたものになるにつれて、これについてもっとよく考える必要があります。

于 2010-01-02T05:58:15.670 に答える
1

他の人がすでに指摘しているように、メソッド「equals」と「hashCode」は異なる目的を果たします。

ObjectのhashCodeメソッドの仕様から、次のことが推測できます。

  • hashCode メソッドが呼び出されたときに、2 つの等しいオブジェクトが同じ整数の結果を返す 必要があります。
  • 等しくないオブジェクトは異なる整数値を返すこと を強くお勧めします

コードは ( tgamblinが提案した変更を考慮して) 基準 (a) を満たしているため、出力は "EQUALS" として得られます。

ただし、(b) に従うことをお勧めします。これにより、クラスのインスタンスがハッシュテーブル キーとして使用される場合のパフォーマンスが向上します。等しくないオブジェクトが同じ hashCode を返し、そのようなクラスがハッシュテーブル キーとして使用されている場合、すべてのオブジェクトが同じバケットにハッシュされ、ハッシュテーブルがリンクリストに劣化し、パフォーマンスが低下します。

于 2010-01-02T08:09:40.897 に答える
1

まず、「ハッシュ値」の v を大文字にする必要があります。

if(oo instanceof Hashvalue)

する必要があります

if (oo instanceof HashValue)
于 2010-01-02T05:57:45.633 に答える
1

HashValueHashvalueは 2 つの異なる識別子です

if(oo instanceof HashValue)あなたのクラス名がそうではHashValueないので動作しますHashvalue

編集 :

hhコードを使用しているときに範囲内にないため、コードは機能しません。

これは機能します:

/* A program to check hashcode values for object
@Author Myth17
 */

class HashValue 
{

   int x;

   public boolean equals(Object oo)
  {
    HashValue hh=new HashValue();
    if(oo instanceof HashValue) 
       hh = (HashValue)oo;

    if(this.x==hh.x)
      return true;
    else
      return false;
  }

   HashValue()
  {
     x=11;
   }

  }

 class  Hashing
 {
     public static void main(String args[])
    {
       HashValue hv=new HashValue();
       HashValue hv2=new HashValue();

      System.out.println(hv.hashCode());
      System.out.println(hv2.hashCode());

      if(hv.equals(hv2))
        System.out.println("EQUAL");
      else
         System.out.println("NOT EQUAL");
    }
  }
于 2010-01-02T05:59:56.337 に答える
0

次のコードでは:

public boolean equals(Object oo) {
    if(oo instanceof Hashvalue) 
        HashValue hh = (HashValue) oo;

    if (this.x == hh.x)
        return true;
    else
        return false;
}

いくつかの問題があります: 1. ハッシュ値がコンパイラによって認識されません。「HashValue」 2 である必要があります。hh は、if ブロックから外れると範囲外になります。したがって、コンパイルエラー。

プログラムを次のように変更すると、機能します。

 public boolean equals(Object oo) {
     if(!(oo instanceof Hashvalue)) 
         return false;

     HashValue hh = (HashValue) oo;
     if (this.x == hh.x)
        return true;
     else
        return false;
}

または、次のように簡潔にすることもできます。

 public boolean equals(Object oo) {
     if(oo instanceof Hashvalue && this.x == ((HashValue) oo).x) 
         return true;
     return false;
}
于 2017-06-23T08:40:41.417 に答える
-1
int x;
public static void main(String args[]){
    E a = new E();
    System.out.println(a.hashcode());
    E b = new E();
    System.out.println(b.hashcode());
}

public int hashcode(){
    return x*17;
}
于 2010-08-28T05:08:42.543 に答える