Hashcode()Vs Equals() [英] Hashcode() Vs Equals()

查看:165
本文介绍了Hashcode()Vs Equals()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这两个类下面。

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

现在我正在做一项研究:

Now I was doing one research that is



  1. 如果我评论hashcode()方法,而不是评论equals()方法,它将使用它允许重复,因为Ram显示两次与内存地址,我得到以下结果..




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()方法,我得到这个结果

2 . If I uncomment hashcode() method and equals () method , I get this result



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(),那么我得到以下结果

3 . If I comment equals() method only and not hashcode() then I get the following result



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

请告诉我们后面有什么共振三种方法..

Please advise what the reson behind there three approaches ..!

推荐答案

HashSet有多个值区。它使用 hashCode()来确定元素属于哪个存储桶,然后在该存储桶中使用 equals()

A HashSet has a number of buckets. It uses the hashCode() to determine which bucket an element belongs in, and then within that bucket, it uses equals() to find if the element exists in that bucket or not.

这些方法的默认实现是 hashCode()使用系统身份哈希码,这可能是它的内存位置,但是是唯一的,因为系统将使用所有合理实际尝试使没有两个对象具有相同的系统身份哈希码,并且等于比较存储器两个对象的位置。 (注意,系统标识哈希码不能保证产生唯一的哈希;而是它真的真的真的很难给你唯一的哈希。参见 Java Bug 6321873 ,以便进一步阅读。)

The default implementations of those methods are hashCode() uses a system identity hashcode, which is probably it's memory location, but is unique in that the system will make an attempt using all "reasonably practical" attempts to make no two objects have the same system identity hashcode, and equals compares the memory locations of the two objects. (Note that system identity hashcode is not guaranteed to produce unique hashes; rather it tries really, really, really hard to give you unique hashes. See Java Bug 6321873 for further reading on the matter.)

有了这些知识,

在第一种情况下,Ram显示在两个不同的桶中,所以两个Ram对象永远不会相互比较。它们使用下面的行进行比较(在Sun实现中,至少)

In your first case, Ram shows up in two different buckets, so the two Ram objects never get compared against eachother. They are compared using the following line (in the Sun implementation, at least)

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

这是对桶中每个对象的迭代。他们的哈希不相等,所以它永远不会检查对象本身是否等于提供的对象。

This is iterating over every object in the bucket. Their hashes aren't equal, so it will never get to the check of determining if the object itself is equal to the one provided.

在你的第二种情况下,它工作

In your second case, it works as you might expect, noting that a person with two different positions and salaries will be considered different people.

在你的第三种情况下,Ram进入同一个桶两次,你可能会期望,两个不同的职位和薪水的人将被视为不同的人。但是因为使用了默认的equals方法,并且两个对象是不同的对象,所以它第二次被添加。

In your third case, Ram enters the same bucket twice. But because the default equals method is used, and the two objects are different objects, it gets added a second time.

它也值得重新迭代duffymo的答案完全忽略你的问题;在99.9%的情况下,我会说这是错误的事情,我们应该先了解你的问题范围。这是极少数情况下,正确呼叫忽略您的问题之一。您应该从不仅覆盖hashcode和equals中的一个。您应该始终不要同时使用两者,也不要同时使用两者,不要只是一个。

It also also worth re-iterating that duffymo's answer completely ignores your question; in 99.9% of cases I would say that's the wrong thing to do, and that we should understand your problem-scope first. This is one of the very few cases where it's the right call to ignore your question. You should never override only one of hashcode and equals. You should always do neither or both, never just one.

这篇关于Hashcode()Vs Equals()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆