4

私はこの2つのクラスの下にあります..

class Emp //implements Comparable
{
      String name,job;
      public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getJob() {
        return job;
    }
    public void setJob(String job) {
        this.job = job;
    }
    public int getSalary() {
        return salary;
    }
    public void setSalary(int salary) {
        this.salary = salary;
    }
    int salary;
      public Emp(String n,String j,int sal)
      {
         name=n;
         job=j;
         salary=sal;
       }
      public void display()
      {
        System.out.println(name+"\t"+job+"\t"+salary);
       }



  public boolean equals(Object o)
      {

         Emp p=(Emp)o;
          return this.name.equals(p.name)&&this.job.equals(p.job) &&this.salary==p.salary;
       }
  /* public int hashCode()
       {
          return name.hashCode()+job.hashCode()+salary;
       }
     */

      /* public int compareTo(Object o)
       {
          Emp e=(Emp)o;
          return this.name.compareTo(e.name);
           //return this.job.compareTo(e.job);
        //   return this.salary-e.salary;

        }*/
} 

そしてもう一つは..

import java.util.*;
class EmpHsDemo
{
      public static void main(String arg[])
      {
          HashSet set=new HashSet();
          set.add(new Emp("Ram","Trainer",34000));
          set.add(new Emp("Ram","Trainer",34000));
          set.add(new Emp("Ravi","Administrator",44000));
          set.add(new Emp("Sachin","Programmer",24000));
          set.add(new Emp("Priyanka","Manager",54000));
          set.add(new Emp("Anupam","Programmer",34000));
          set.add(new Emp("Sachin","Team Leader",54000));
          System.out.println("There are "+set.size()+" elements in the set.");
          System.out.println("Content of set are : ");
          Iterator itr=set.iterator();
          while(itr.hasNext())
          {
            Emp e=(Emp)itr.next();
            System.out.print(e.hashCode()+"\t");   
            e.display();
          }   


          System.out.println("**********************************");
        Emp e1=new Emp("Ravi","Administrator",44000);
        System.out.println("Removing following Emp from the set...");
        System.out.print(e1.hashCode()+"\t");
        e1.display();
        set.remove(e1);
        System.out.println("No. of elements after removal "+set.size());
       /* Emp e2=new Emp("Anupam","Programmer",34000);
        System.out.println("Searching following Emp in the set...");
        System.out.print(e2.hashCode()+"\t");
        e2.display();
        System.out.println("Results of searching is : "+set.contains(e2));*/
      }
}

今、私はある研究をしていました

  1. hashcode() メソッドにコメントを付け、equals () メソッドにコメントを付けない場合は、使用されるメモリ アドレスとともに Ram が 2 回表示されるため、複製が許可されます。次の結果が得られます。
There are 7 elements in the set.
Content of set are : 
374283533   Priyanka    Manager 54000
1660364311  Ram Trainer 34000
1340465859  Ravi    Administrator   44000
2106235183  Sachin  Programmer  24000
2031692173  Ram Trainer 34000
603737068   Anupam  Programmer  34000
148669801   Sachin  Team Leader 54000
**********************************
Removing following Emp from the set...
1807500377  Ravi    Administrator   44000
No. of elements after removal 7

2. hashcode() メソッドと equals () メソッドのコメントを外すと、この結果が得られます

There are 6 elements in the set.
Content of set are : 
1546622676  Sachin  Team Leader 54000
-302767206  Anupam  Programmer  34000
149315535   Ravi    Administrator   44000
199998062   Sachin  Programmer  24000
1407883922  Priyanka    Manager 54000
597555555   Ram Trainer 34000
**********************************
Removing following Emp from the set...
149315535   Ravi    Administrator   44000
No. of elements after removal 5

3. equals() メソッドのみをコメントし、hashcode() をコメントしない場合、次の結果が得られます

There are 7 elements in the set.
Content of set are : 
1546622676  Sachin  Team Leader 54000
-302767206  Anupam  Programmer  34000
149315535   Ravi    Administrator   44000
199998062   Sachin  Programmer  24000
1407883922  Priyanka    Manager 54000
597555555   Ram Trainer 34000
597555555   Ram Trainer 34000
**********************************
Removing following Emp from the set...
149315535   Ravi    Administrator   44000
No. of elements after removal 7

3つのアプローチの背後にある理由を教えてください..!

4

5 に答える 5

7

あなたが投稿したすべての情報を読む価値はありません。

Joshua Blochは、hashCodeとequalsを一緒にオーバーライドする必要があると述べています。 例外なく、これを行う方法は次のとおりです。

于 2012-08-07T17:20:25.350 に答える
5

HashSet には多数のバケットがあります。を使用してhashCode()、要素が属するバケットを判別し、そのバケット内でequals()、要素がそのバケットに存在するかどうかを確認します。

これらのメソッドのデフォルトの実装hashCode()は、システム ID ハッシュコードを使用します。これはおそらくメモリの場所ですが、2 つのオブジェクトが同じシステム ID ハッシュコードを持たないようにするために、システムはすべての「合理的に実用的な」試みを使用して試行するという点で独特です。 and equals は、2 つのオブジェクトのメモリ位置を比較します。(システム ID ハッシュコードは一意のハッシュを生成することが保証されていないことに注意してください。むしろ、一意のハッシュを生成するのは非常に困難です。この問題の詳細については、 Java Bug 6321873を参照してください。)

この知識があれば、実装されているか、デフォルトの実装を使用しているかに関係なく、さまざまな方法を論理的に適用して、さまざまなアプローチを予測できます。

最初のケースでは、Ram は 2 つの異なるバケットに表示されるため、2 つの Ram オブジェクトが互いに比較されることはありません。それらは次の行を使用して比較されます (少なくとも Sun の実装では)

if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

これは、バケット内のすべてのオブジェクトを反復しています。それらのハッシュは等しくないため、オブジェクト自体が提供されたものと等しいかどうかを判断するチェックは行われません。

2 番目のケースでは、期待どおりに機能し、2 つの異なる役職と給与を持つ人物は異なる人物と見なされることに注意してください。

3 番目のケースでは、Ram は同じバケットに 2 回入ります。しかし、デフォルトの equals メソッドが使用され、2 つのオブジェクトが異なるオブジェクトであるため、もう一度追加されます。

また、duffymo の回答があなたの質問を完全に無視していることを繰り返す価値もあります。99.9% のケースで、それは間違ったことであり、まず問題の範囲を理解する必要があると言えます。これは、質問を無視するのが適切な数少ないケースの 1 つです。hashcode と equals の一方のみを上書きしないでください常にどちらかまたは両方を実行する必要があります。一方だけを実行することはできません。

于 2012-08-07T17:24:30.857 に答える
3

1. 2 つのオブジェクトが等しい場合、それらは になりますsame hashcode

2. 2 つのオブジェクトが等しいsame hascode,場合は、互いに equals() を呼び出して、等しいかどうかを確認する必要があります。

3.ハッシュコードが一致する場合、両方が等しい必要はありません。

4.したがって、メソッドをオーバーライドする場合は、メソッドもオーバーライドする必要があることが非常に重要です。equals()hashcode()

5. HashSetオブジェクトを取得するときに、このオブジェクトが に収まる場所をチェックし、 同じハッシュコードHashSetを持つオブジェクトがあるかどうかを調べます。もしあれば、両方が をラベルとしてバケットに取り込まれ、互いに呼び出して、本当に平等です。same hashcodeequals()

于 2012-08-07T17:24:34.067 に答える
0

corsiKa さんが正解しました。物事を単純化するために、いくつかのポイントを追加するだけです。@ user1582269 Set Algo を使用しており、Hashing はデータ構造が使用されています。Set の概念に従って、Set の各要素は一意である必要があります。要素の複製は許可されていません。どの要素に基づいて一意になりますか? この一意性を実現するには、equals() メソッドをオーバーライドする必要があります。つまり、Emp 1 は Emp 2 とは異なる必要があります。これで、 Hash Data Structure を使用しています。ハッシュは、要素がどのように保存、取得、検索されるかを保証します。ハッシュを効率的に機能させるには、衝突が起こらないように、ハッシュ関数、つまり hashCode() をオーバーライドする必要があります。

ハッシュの詳細については、corsiKa の説明を参照してください。したがって、hashCode() をオーバーライドしない場合、デフォルトの hashCode() 実装は、たとえば 4 などのバケット ID (配列内のインデックスを想定) を返します。 hashCode ie 4 が返された場合、empX と empY の間で衝突が発生します。

これで疑問が解消されることを願っています。

于 2012-08-07T17:48:03.740 に答える
0

HashSetHashMapデータの内部表現として使用します。HashSet.add()そして 値にHashSet.remove()取り組みhashます(メソッドで提供しますhashCode()。コメントアウトするとすぐにhashCode()、すべての賭けがオフになります.

私の心はこれについてダッフィーモにいくらか嘘をついていますが、一方で、あなたの権威が理解せずにそう言ったので、私は何かをすることにほとんど反対です.

于 2012-08-07T17:31:48.077 に答える