Java: the difference and connection between hashCode() and equals()

1. The role of hashCode() and equals()

In Java, the hashCode() method and equals() method are used to compare whether two objects are equal.

2. The difference between hashCode() and equals()

The difference between them is introduced from two perspectives: one is performance and the other is reliability.

1. Since equals() can achieve the function of comparison, why hashCode()?

Because the comparison of equals in the rewritten equals() is generally more comprehensive and complicated, although the reliability is good, it will lead to lower efficiency. However, if you use hashCode() for comparison, you only need to generate a hash value for comparison. high efficiency.

2. Why is equals() even if hashCode() is so efficient?

Because hashCode() is not completely reliable, sometimes different objects generate the same hashcode (probable problems in generating hash value formulas, hash conflicts), so hashCode() can only be said to be reliable most of the time, not Absolutely reliable, so we can draw conclusions

  • equals() The hashCode() of two objects that are equal must be equal, that is, the comparison with equals() is absolutely reliable.
  • Two objects with equal hashCode() have equals() not necessarily equal, that is, hashCode() is not absolutely reliable.

3. Notes on the use of hashCode() and equals()

1. If you need a lot of and fast comparison, it is obviously too inefficient to use equals(), so the solution is, whenever you need to compare, first use hashCode() to compare, if hashCode() is different, It means that the two objects are definitely not equal (that is, you don’t need to use equals() to compare again). If the hashCode() is the same, then compare their equals(). If equals() is also the same, it means this The two objects are really the same, which can greatly improve the efficiency and ensure the absolute correctness of the comparison!

2. This kind of large and fast object comparison is generally used in the hash container, such as HashSet, HashMap, HashTable, etc. For example, if the object in the HashSet requires that the object cannot be repeated, it must compare each object added internally. And his comparison rule is as mentioned above, first hashCode(), if the hashCode() is the same, then use equals() to verify, if the hashCode() are all different, it must be different, so the efficiency of comparison is very high.

3. However, hashCode() and equals() are methods in the basic class Object, and like equals(), hashCode() in Object only returns the address of the current object. If this is the case, then we are the same Class, new two objects, because their addresses in memory are different, their hashCode() is different, so this is obviously not what we want, so we must rewrite the hashCode() method of our class, that is, a class, Return a unique hash value in hashCode().

class User{
    
    
	int id;
	String name;
	
	public int hashCode(){
    
    
		return id*name.hashCode();
	} 
}

Since it is the internal variables num and name that identify this class, we will return a hash value based on them as the only hash value of this class.

So if our object wants to be put into the hashSet and take advantage of the characteristics of the hashSet (that is, it does not contain the same object), then we have to rewrite the hashCode() and equals() methods of our class. Classes like String, Integer, etc. have rewritten these two methods internally.

Of course, if we just want to compare whether the two objects are the same, we only need to rewrite one equals(), and then use equals() to compare.

4. Expansion

1. Alibaba development specifications clearly stipulate:

As long as equals is rewritten, hashCode must be rewritten;

Because Set stores unique objects, which are judged based on hashCode and equals, the objects stored in Set must rewrite these two methods;

If a custom object is used as the key of the Map, then hashCode and equals must be rewritten;

String rewrites the hashCode and equals methods, so we can use String objects as keys very happily;

2. When does it need to be rewritten?

In general, there is no need to overload hashCode. Only when the class needs to be placed in a collection of hash structures such as HashTable, HashMap, HashSet, etc., will the hashCode be overloaded.

3. Then why overload hashCode?

If you rewrite equals, for example, based on the content of the object, and leave the implementation of hashCode unchanged, then it is very likely that two objects are clearly "equal" but the hashCode is different.

In this way, when you use one of them as a key to save it in a hashMap, hasoTable or hashSet, and then use the "equal" to find the other as the key value to find them, you will not find it at all.

Example explanation The
Insert picture description hereInsert picture description here
printed value is:
1901116749
1807500377
355165777
1414159026
1569228633
778966024
We hope that the premise of two HashCodeClass equals is that the str0, dou0, and int0 of the two HashCodeClass are equal. OK, then there is a problem that this class does not override the hashCode() method.
Now my HashCodeClass is not assigned an initial value, so these 6 HashCodeClass should be all equals. If we take HashSet as an example, the size of the table itself of HashMap inside HashSet is 16, then six HashCodes modulo 16 are 13, 9, 1, 2, 9, and 8, respectively. The first is placed in the position of table[13], the second is placed in the position of table[9], and the third is placed in the position of table[1]. . . But obviously there are all 6 HashCodeClasses of equals, how can this be done? What HashSet itself requires is that the equals objects are not duplicated. Now there are 5 equals objects in the set (because two of the calculated modulus are both 9).
So what should we do? Rewrite the hashCode method, and generate an algorithm that is as unique as possible based on str0, dou0, and int0, so as to ensure that the two HashCodeClasses with equal str0, dou0, and int0 have the same HashCode. This is what the equals method must be Try to rewrite the reason for the hashCode method.

4. Why equals() is equal, hashCode must be equal, and hashCode is equal, but equals is not required to be equal?

Because the small memory block is accessed according to the hashCode, the hashCode must be equal.

HashMap obtains an object to compare the hashCode of the key to be equal and equals to true.

The reason why hashCode is equal, but equals can be different. For example, ObjectA and ObjectB both have attribute name, then hashCode is calculated by name, so hashCode is the same, but the two objects are of different types, so equals is false.

5. Why do I need hashCode?

Small memory blocks can be found quickly through hashCode.

Comparing through hashCode is faster than equals method. When get, compare hashCode first. If hashCode is different, return false directly.

Guess you like

Origin blog.csdn.net/qq_32505207/article/details/108421012