哈希码和等于

时间:2010-01-02 05:55:21

标签: java hashcode

equalshashCode方法必须一致,这意味着当两个对象根据equals方法相等时,它们的hashCode方法应该返回相同的哈希值。< / p>

如果我们不覆盖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");
    }
}

为什么取消注释该行会产生编译错误?

如果对象具有不相等的哈希码,那么即使默认哈希码变化,它们为什么显示相等?

7 个答案:

答案 0 :(得分: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时,false不在范围内。

  2. 当你比较两个不是HashValues的东西(即抛出异常)时,第一个if语句应该确保函数根本不运行,或者它应该返回false因为HashValues永远不会等于其他类型的对象。我通常更喜欢将public boolean equals(Object oo) { if(!(oo instanceof Hashvalue)) { return false; } HashValue hh = (HashValue)oo; return (this.x == hh.x); } 返回到抛出异常。

  3. 第二个if语句是多余的,因为您只是返回条件评估的内容。

  4. 像这样重写你的方法:

    HashValue

    这也不太对劲。要确保所有相等的对象具有相同的哈希码,您必须覆盖// inside HashValue int hashCode() { return x; } 中的hashCode(),并且必须确保它符合保证。在这里,您可以添加:

    int

    实现很简单,因为你的对象只是{{1}}的包装器。随着对象越来越复杂,你需要更加努力地思考。

答案 1 :(得分:6)

平等仅由方法equals()决定。方法hashCode()用于其他情况,例如Map或Set。在实际调用equals(效率)之前,它有点像先决条件或提示。因此假设如果2个对象相等(即equals()返回true),则它们的hashCodes()必须返回相同的值。

所以在你的代码中,2个对象是相等的,只要你的overriden equals()返回true,无论hashCode()做什么。在比较相等性时,根本不调用hashCode()。

This question有关于equals()和hashCode()之间关系的更深入信息。

答案 2 :(得分:1)

对于初学者,您需要在“Hashvalue”

中大写v
if(oo instanceof Hashvalue)

应该是

if (oo instanceof HashValue)

答案 3 :(得分:1)

HashValue Hashvalue 是两个不同的标识符

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

答案 4 :(得分:1)

正如其他人已经指出的那样,方法“等于”而“hashCode”用于不同的目的。

根据 Object 中的hashCode方法的规范,可以推断:

  • 必需当对它们调用hashCode方法时,两个相等的对象应该返回相同的整数结果
  • 高度推荐,不等对象返回不同的整数值

您的代码(考虑到 tgamblin 已提出)满足条件(a),因此您将输出视为“EQUALS”。

但是遵循(b)是一个好习惯,因为当使用类的实例作为哈希表键时,这会带来更好的性能。当不相等的对象返回相同的hashCode并且如果将这样的类用作散列表键时,则每个对象散列到同一个桶,并且散列表将退化为链接列表,从而导致性能降低。

答案 5 :(得分: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。它应该是&#34; HashValue&#34; 2.在if-block之外,hh超出了范围。因此,编译错误。

您可以将程序更改为以下程序,它将起作用:

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

答案 6 :(得分:-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;
}