JAVA hashCode USES methods in detail

  • 2020-04-01 02:26:13
  • OfStack

I. introduction of problems
When we talk about hashCode, we have to say equals. Both are in the Object class, and since the Object class is the base class for all classes, we can override both methods in all classes.
For a clearer understanding, you need to know the container Collection, Set, list, Map(key value is not repeatable), Set element order is not repeated, list element order is repeatable, so how does the JVM determine the different elements?
The JVM USES a hash method (the hash address is not necessarily the actual physical address) to see if there is any content on the address. If there is no hash, the same object does not exist...
  Let's break it down...

Ii. Problem analysis
First, both equals() and hashcode() are inherited from the object class, and the equals() method is defined in the object class as follows:


public boolean equals(Object obj) { 
    return (this == obj); 
}

It is clear from the declaration that the address values of the two objects are being compared (that is, whether the references are the same). But let's be clear, when String, Math, and Integer, Double... These wrapper classes already overwrite the object class when using the equals() method
Equals () method.

2. Next is the hashcode() method, which is defined in the object class as follows:
Public native int hashCode ();
Description is a local method whose implementation is local machine dependent.


public int hashCode() { 
    int h = hash; 
    if (h == 0) { 
   nt off = offset; 
   char val[] = value; 
   int len = count; 
 
   for (int i = 0; i < len; i++) { 

  h = 31*h + val[off++]; 
   } 
   hash = h; 
    } 
    return h; 
}

Explain the procedure: s[0]*31^(n-1) + s[1]*31^(n-2) +... + s[n-1], you can see that the hash address is not necessarily the actual memory address.

  3. Several specifications
If you override the equals(Object obj) method, it is necessary to override the hashcode() method to ensure that two objects whose result is true by the equals(Object obj) method have equal hashcode() return values. To put it simply: "if two objects are the same, then their hashcode should be equal." Note, though, that this is just the specification, and if you must write a class that returns true equals(Object obj) and hashcode() returns two unequal values, both compile and run without error. This is a violation of the Java specification, however, and the program is buggy.
If equals(Object obj) returns false, that is, two objects are "not the same," there is no requirement to call the hashcode() method on the two objects to get two different Numbers (more confirmation that the hash address is not necessarily the actual memory address). To put it simply: "if two objects are different, their hashcode may be the same."
According to these two norms, it is not difficult to get the following inference:
1. If two objects are equals, the Java runtime environment assumes that their hashcode must be equal.
2. If two objects are not equals, their hashcode is likely to be equal.
3. If two objects hashcode are equal, they are not necessarily equals (I understand this is due to hash collisions).
4. If two objects hashcode are not equal, they must not equals.

Problem solving
  Test the use of hashCode and equals methods...


import java.util.HashMap;  
import java.util.Map;  
class A {  

    @Override  
    public boolean equals(Object obj) {  
   System.out.println(" judge equals");  
   return true;  
    }  

    @Override  
    public int hashCode() {  
   System.out.println(" judge hashcode");  
   return 1;  
    }  
}  

  
public class Test {  

    public static void main(String[] args) {  
   Map<A,Object> map = new HashMap<A, Object>();  
   map.put(new A(), new Object());  
   map.put(new A(), new Object());  
 

   System.out.println(map.size());  
    }  

}

Output:

Judge hashcode 
Judge hashcode 
Judge equals 
2


The results are analyzed as follows:
As you can see, the JRE calls the hashcode() method of the object new A(). Where: the first line of "judge hashcode" printed out is the first map.put(new A(), new Object()) printed out. The next "judge hashcode" and "judge equals" are printed by the second map.put(new A(), new Object()). When the first map.put(new A(), new Object()), obviously, there is no equivalent, because there is nothing in the map yet, so at this point hashcode is not equal, there is no need to call the equals(Object obj) method. When the second map.put (new A (), new Object ()), the JRE found that there were two identical hashcodes in the map (because I overwrote the hashcode () method of class A, which always returns 1), so it was necessary to call the equals (Object obj) method to judge. Then I find that the two objects are not equals(because I override the equals(Object obj) method, which always returns false). This is the end of the judgment, the judgment result: the two stored objects are not the same object. So when the length of the map is printed, the result is: 2.

Iv. Certain notes
We should also note that the Java language requires equals(), which must be followed:

Symmetry: if x.quals (y) returns true, then y.quals (x) should also return true.
Reflectivity: x.exquals (x) must return "true".
Transitivity: if x.quals (y) returns true, and y.quals (z) returns true, then z.quals (x) should also return true.
Consistency: if x.quals (y) returns true, it doesn't matter how many times you repeat x.quals (y), as long as the x and y contents remain the same.
In any case, x.exquals (null) always returns "false"; X.equals (objects of a different type than x) always returns false

  The above five points are the rules that must be followed when overriding the equals() method. If there are unexpected results, please follow them.


Related articles: