Principles of hashCode and identityHashCode

hashCode concept

HashCode is an int number calculated by jdk according to the address of the object, that is, the hash code value of the object, which represents the storage location of the object in the memory.

We all know that the hashCode() method is a method provided by the top class Object class, and all classes can override the hashCode method.

We also know that the equals method is often rewritten when comparing whether a class is the same. It is worth noting that the hashCode method must also be rewritten when the equals method is rewritten. If the hashCode method of an object is called multiple times, the same number must be returned. This is also the norm that must be followed, otherwise it will cause the necessary harm.

hash conflict

When two objects have the same equals, the hashCode requirements must also be the same, but the reverse is not necessarily true. Two objects correspond to a hashCode, but equals are not equal. . This is the legendary hash conflict. HashMap stores values ​​in the form of an array of hashCode modulo. Will the same two object hashCodes cause the value of the previous object to be overwritten? The answer is no, because it uses another linked list data structure to resolve hash conflicts. Even if the hashCodes of two objects are the same, they will be placed in the linked list at the current array index position.

hashCode design

Obviously the hashCode() of "str1" and "str2" are the same, but equals() is false, because in a hash table (also called a hash table), hashCode() is equal to the hash value of two key-value pairs Equal, but the hash value is equal, and it does not necessarily result in the key-value pair being equal.

HashSet is implemented by HashMap and is used to store non-duplicated data. How to judge whether the objects in it are duplicates? To judge whether the object is duplicate is to judge whether the attributes in the object are all the same. At this time, the equals method must be rewritten to compare all the values ​​in the object, instead of comparing the reference addresses, and comparing the reference addresses, they are never equal, unless they are The same object. The performance of the process of comparing through equals is very poor, so with the design of hashCode, the comparative equals of simple two numbers cannot be compared, so you can first determine whether it is the same object by comparing the hashCode of the object. When the hashCode is different, it must not be the same object. On the contrary, if the hashCode is the same and equals or == is the same, it must be the same object. So first compare the hashCode of the number and then compare equals or ==, so the efficiency will be significantly improved.

If we rewrite equals without rewriting the hashCode method, the hashCode of multiple objects with the same attribute value will definitely be different. At this time, when the key is put into the map, there will be multiple such keys. And the scene where the object is not used as the key is also not able to achieve the effect of HashSet de-duplication.

The hashCode() of the two objects is the same, equals() is not necessarily true. Code example:

String str1 = "abc";
String str2 = "ccc";
System.out.println("str1 hashCode: " + str1.hashCode());
System.out.println("str2 hashCode: " + str2.hashCode());
System. out. println(str1. equals(str2));

The result of execution:

str1 hashCode: 1179395
str2 hashCode: 1179395
false

identityHashCode

identityHashCode is a native method provided in System, java.lang.System#identityHashCode.
The difference between identityHashCode and hashCode is that identityHashCode will return the hashCode of the object, regardless of whether the object overrides the hashCode method.
Example

public static void main(String[] args) {
    
    
    String str1 = new String("abc");
    String str2 = new String("abc");
    System.out.println("str1 hashCode: " + str1.hashCode());
    System.out.println("str2 hashCode: " + str2.hashCode());
    System.out.println("str1 identityHashCode: " + System.identityHashCode(str1));
    System.out.println("str2 identityHashCode: " + System.identityHashCode(str2));

    User user = new User("test", 1);
    System.out.println("user hashCode: " + user.hashCode());
    System.out.println("user identityHashCode: " + System.identityHashCode(user));
}

Output result:

str1 hashCode: 96354
str2 hashCode: 96354
str1 identityHashCode: 1173230247
str2 identityHashCode: 856419764
user hashCode: 621009875
user identityHashCode: 621009875

Result analysis:

1. The hashCode of str1 and str2 are the same, because the String class rewrites the hashCode method, which determines the value of the hashCode according to the value of the String, so as long as the value is the same, the hashCode will be the same.

2. The identityHashCode of str1 and str2 are different. Although String rewrites the hashCode method, identityHashCode always returns the hash value generated according to the physical memory address of the object, so the physical address of each String object is different, and the identityHashCode will also be different.

3. The User object does not override the hashCode method, so the hashCode and identityHashCode return the same value.

Conclusion The
hashCode method can be rewritten and return the rewritten value. The identityHashCode will return the hash value of the object regardless of whether the object overrides the hashCode method.

Guess you like

Origin blog.csdn.net/weixin_44371237/article/details/114656810