Hashcode and equals

后端 未结 7 2343
死守一世寂寞
死守一世寂寞 2020-11-30 14:00

equals and hashCode method must be consistent, which means that when two objects are equal according to equals method their hash

相关标签:
7条回答
  • 2020-11-30 14:33

    In the following code:

    public boolean equals(Object oo) {
        if(oo instanceof Hashvalue) 
            HashValue hh = (HashValue) oo;
    
        if (this.x == hh.x)
            return true;
        else
            return false;
    }
    

    there are a couple of issue: 1. Hashvalue is not recognised by your compiler. It should be "HashValue" 2. hh is out of scope once out of if-block. Hence, compiler error.

    You can change your program to following and it will work:

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

    or you can make it more concise as follows:

     public boolean equals(Object oo) {
         if(oo instanceof Hashvalue && this.x == ((HashValue) oo).x) 
             return true;
         return false;
    }
    
    0 讨论(0)
  • 2020-11-30 14:34

    HashValue and Hashvalue are two different identifiers

    if(oo instanceof HashValue) works because your class-name is HashValue not Hashvalue

    EDIT :

    Your code doesn't work because hh isn't in scope when you are using it.

    This works:

    /* 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");
        }
      }
    
    0 讨论(0)
  • 2020-11-30 14:37
    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;
    }
    
    0 讨论(0)
  • 2020-11-30 14:38

    As others have already pointed out it the methods "equals" and the "hashCode" serve different purposes.

    From the specification of hashCode method in Objectone can infer that:

    • It is required that two equal objects should return same integer result when hashCode method is invoked on them
    • It is highly recommended that unequal objects return distinct integer values

    Your code (taking into consideration the change tgamblin has proposed) satisfies criteria (a) hence you get the output as "EQUALS".

    But is a good practice to follow (b) as this results in better performance when instance of the class are used as hashtable keys. When unequal objects return the same hashCode and if such a class is used as hashtable key, then every object hashes to the same bucket, and hashtable would degenerate to a linkedlist leading to reduced performance.

    0 讨论(0)
  • 2020-11-30 14:52

    Equality is only determined by method equals(). And method hashCode() is used in other situations, like by Map or Set. It is somewhat like a pre-condition or hint before actually calling equals (for efficiency). So it is assumed that if 2 objects are equal (that is, equals() returns true), then their hashCodes() must return the same value.

    So in your code, 2 objects are equal, as long as your overriden equals() returns true, no matter what hashCode() does. hashCode() is not called at all when comparing for equality.

    This question has more in-depth information regarding to the relationship between equals() and hashCode().

    0 讨论(0)
  • 2020-11-30 14:53

    First, in that line, you need to change Hashvalue to HashValue, since your class is actually called HashValue.

    Then, uncommenting the line gives you this:

    public boolean equals(Object oo) {
        if(oo instanceof HashValue)
            HashValue hh = (HashValue)oo;
    
        if (this.x==hh.x) {
            return true;
        } else {
            return false;
        }
    }
    

    There are a few things wrong with this:

    1. This doesn't compile because hh isn't in scope when you end up using it.

    2. The first if statement should either make sure that the function doesn't run at all when you compare two things that aren't HashValues (i.e. throw an exception), or it should return false because HashValues are never equal to other types of objects. I generally prefer returning false to throwing an exception.

    3. The second if statement is redundant, because you're just returning what the condition evaluates to.

    Rework your method like this:

    public boolean equals(Object oo) {
        if(!(oo instanceof Hashvalue)) {
            return false;
        }
    
        HashValue hh = (HashValue)oo;
        return (this.x == hh.x);
    }
    

    This isn't quite right, either. To make sure that all equal objects have the same hash code, you have to override hashCode() in HashValue, and you must make sure that it lives up to the guarantee. Here, you could just add this:

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

    The implementation is trivial because your object is just a wrapper around an int. You'll need to think harder about this as your objects get more sophisticated.

    0 讨论(0)
提交回复
热议问题