8

equalshashCode方法必须一致,这意味着当两个对象根据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

首先,在该行中,您需要更改HashvalueHashValue,因为您的课程实际上被称为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 语句应该确保在比较两个不是 HashValues 的东西时函数根本不运行(即抛出异常),或者它应该返回false,因为 HashValues 永远不等于其他类型的对象。我通常更喜欢返回false抛出异常。

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

像这样重做你的方法:

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

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

这也不完全正确。为了确保所有相等的对象具有相同的哈希码,您必须覆盖hashCode()in HashValue,并且必须确保它符合保证。在这里,您可以添加以下内容:

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

实现很简单,因为您的对象只是int. 随着您的对象变得越来越复杂,您需要更加仔细地考虑这一点。

于 2010-01-02T05:58:15.670 回答
6

相等性仅由方法 equals() 确定。并且方法 hashCode() 用于其他情况,例如 Map 或 Set。它有点像实际调用 equals 之前的前提条件或提示(为了提高效率)。所以假设如果 2 个对象相等(即 equals() 返回 true),那么它们的 hashCodes() 必须返回相同的值。

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

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

于 2010-01-02T06:34:31.393 回答
1

对于初学者,您需要将“Hashvalue”中的 v 大写

if(oo instanceof Hashvalue)

应该

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

HashValueHashvalue是两个不同的标识符

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 回答
1

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

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

  • 要求两个相等的对象在调用 hashCode 方法时返回相同的整数结果
  • 强烈建议不相等的对象返回不同的整数值

您的代码(考虑到tgamblin提出的更改)满足标准(a),因此您得到的输出为“EQUALS”。

但是遵循 (b) 是一个很好的做法,因为当类的实例用作哈希表键时,这会带来更好的性能。当不相等的对象返回相同的 hashCode 并且这样的类被用作 hashtable 键时,那么每个对象都散列到同一个桶中,并且 hashtable 将退化为一个链表,从而导致性能下降。

于 2010-01-02T08:09:40.897 回答
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 不被您的编译器识别。它应该是“HashValue” 2。一旦超出 if 块,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;
}
于 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 回答