Detail the role of hashCode in Java

  • 2020-06-15 09:08:13
  • OfStack

Detail the role of hashCode in Java

The following is the official documentation definition of HashCode:


hashcode Method returns the hash code value of the object. Support for this method is provided for hash tables 1 Some advantages, for example, java.util.Hashtable  The hash table provided.   
 
hashCode  The general agreement is:   
 in  Java  During application execution, the same as 1 Object  hashCode  Method must 1 Returns the same integer, if on the object  equals  The information used in the comparison has not been modified. On the one 1 Application-specific 1 The execution to the same 1 Another of the applications 1 The integer does not need to be maintained 1 Cause.   
 If according to  equals(Object)  Method, the two objects are equal, then called on each of the two objects  hashCode  Methods must all produce the same integer result.   
 Not in the following cases   Is required: if based  equals(java.lang.Object)  Method where two objects are not equal, then any object in two objects 1 Call on object  hashCode  Methods are bound to produce different integer results. Programmers should know, however, that generating different integer results for unequal objects can improve the performance of hash tables.   
 In fact, by  Object  The class definition  hashCode  Methods do return different integers for different objects. (this 1 Usually by converting the internal address of the object to 1 Integer to achieve, but  JavaTM  Programming languages don't require this kind of implementation skill.)   
 
 when equals When a method is overridden, it is usually necessary to overwrite it  hashCode  Methods to maintain  hashCode  Method, which states that equal objects must have equal hash codes.  

The above definition of the official document can be summarized as the following key points:

1. hashCode exists mainly for the convenience of searching, such as Hashtable, HashMap, etc. hashCode is used to determine the storage address of objects in the hash storage structure;
2. If two objects are the same, equals(Java.lang.Object) method is applicable, then hashCode1 of the two objects must be the same;
3. If the equals method of the object is overridden, then the hashCode method of the object is overridden as much as possible, and the object used by hashCode is generated. 1 must be the same as the one used in equals method, otherwise the second point mentioned above will be violated;
4. If two objects have the same hashCode, it does not mean that they are the same, which means that it does not apply to the equals(Java.lang.Object) method, only that the two objects are in a hash storage structure, such as Hashtable, where they are "stored in the same basket".

Induction 1 is that hashCode is used for lookup, and equals is used to compare the equality of two objects. The following is a copy of a response from someone else:


1.hashcode It's used for lookup, and if you've studied data structures you should know that it's used for searching and sorting 1 Chapter there  
 Let's say there's a place in memory that looks like this  
0 1 2 3 4 5 6 7  
 And I have a class that has a field called ID, I'm going to store this class above 8 A position of 1 If you don't use hashcode And if you store it arbitrarily, then when you look it up you need to go here 8 One by one to find, or to use 2 Rule of thirds 1 Class.  
 But if use hashcode That would make it a lot more efficient.  
 We have a field in this class called ID, So let's define our hashcode for ID % 8 , and then store our class where we get the remainder. Like ours ID for 9 . 9 In addition to 8 The remainder of 1 , so we'll just leave that class there 1 This position, if ID is 13 , and the remainder is 5 , so let's put this class in 5 This position right here. That way, you can pass when you look up the class later ID In addition to  8 Find the remainder and go straight to where you put it.  
 
2. But if two classes have the same hashcode How do we do that (let's assume the class above ID Not only 1 Of, of, of 9 Divided by the 8 and 17 Divided by the 8 All of the remainder 1 "Is it legal?" the answer is: Yes. So how do you tell? This is where the definition comes in  equals .  
 In other words, let's pass first  hashcode To determine whether two classes are stored in a bucket, but there might be many classes in the bucket, so we need to go through it again  equals  To find our class in this bucket.  
 Then. Rewrite the equals() Why do I have to rewrite it hashCode() ?  
 Think about it. You're gonna be here 1 You have to find the bucket first. You don't rewrite it hashcode() To find the bucket, light rewrite equals() What's the use  

Finally, let's look at a concrete example,


public class HashTest { 
  private int i; 
 
  public int getI() { 
    return i; 
  } 
 
  public void setI(int i) { 
    this.i = i; 
  } 
 
  public int hashCode() { 
    return i % 10; 
  } 
 
  public final static void main(String[] args) { 
    HashTest a = new HashTest(); 
    HashTest b = new HashTest(); 
    a.setI(1); 
    b.setI(1); 
    Set<HashTest> set = new HashSet<HashTest>(); 
    set.add(a); 
    set.add(b); 
    System.out.println(a.hashCode() == b.hashCode()); 
    System.out.println(a.equals(b)); 
    System.out.println(set); 
  } 
} 

The output is:


true 
false 
[com.ubs.sae.test.HashTest@1, com.ubs.sae.test.HashTest@1] 

In the above example, we have simply rewritten the hashCode method. As you can see from the above results, although the hashCode of two objects is equal, the two objects are not actually equal. Instead of overriding the equals method, the default equals method of object is called to compare the references of the two objects to see if they are the same, showing that they are different objects and that the references of the two objects must be indeterminate. Here we put the generated object in HashSet, while HashSet can only hold 1 object, that is, the same object (for equals method) will only hold 1 object, but there are actually two objects a,b are both placed in HashSet, so HashSet loses its meaning.

At this point, we add equals method to:


public class HashTest { 
  private int i; 
 
  public int getI() { 
    return i; 
  } 
 
  public void setI(int i) { 
    this.i = i; 
  } 
 
  <span style="color:#3366FF;"><strong>public boolean equals(Object object) { 
    if (object == null) { 
      return false; 
    } 
    if (object == this) { 
      return true; 
    } 
    if (!(object instanceof HashTest)) { 
      return false; 
    } 
    HashTest other = (HashTest) object; 
    if (other.getI() == this.getI()) { 
      return true; 
    } 
    return false; 
  }</strong></span> 
 
  public int hashCode() { 
    return i % 10; 
  } 
 
  public final static void main(String[] args) { 
    HashTest a = new HashTest(); 
    HashTest b = new HashTest(); 
    a.setI(1); 
    b.setI(1); 
    Set<HashTest> set = new HashSet<HashTest>(); 
    set.add(a); 
    set.add(b); 
    System.out.println(a.hashCode() == b.hashCode()); 
    System.out.println(a.equals(b)); 
    System.out.println(set); 
  } 
} 

The result is as follows:


true 
true 
[com.ubs.sae.test.HashTest@1] 

As you can see from the results, the two objects are now exactly equal, and there is only one copy of the object in HashSet.

Thank you for reading, I hope to help you, thank you for your support to this site!


Related articles: