On hashcode method in Java (recommended)

The data structure of hash table must be familiar to most people, and hash table will be used in many places to improve search efficiency. There is a method in the object class of Java:

According to the declaration of this method, this method returns a value of type int and is a local method. Therefore, no specific implementation is given in the object class.

Why does the object class need such a method? What does it do? Today, let's discuss the hashcode method in detail.

I Function of hashcode method

For programming languages containing container types, hashcode is basically involved. The same is true in Java. The main function of hashcode method is to cooperate with hash based sets, such as HashSet, HashMap and hashtable.

Why do you say that? Consider a case, when inserting an object into a set, how to judge whether the object already exists in the set? (Note: duplicate elements are not allowed in the collection)

Perhaps most people will think of calling the equals method to compare one by one. This method is indeed feasible. However, if there are 10000 pieces of data or more in the set, if the equals method is used to compare them one by one, the efficiency must be a problem. At this time, the function of the hashcode method is reflected. When the collection wants to add a new object, first call the hashcode method of the object to get the corresponding hashcode value. In fact, in the specific implementation of HashMap, a table will be used to save the hashcode value of the saved object. If there is no such hashcode value in the table, it can be saved directly, No more comparisons; If the hashcode value exists, its equals method will be called to compare with the new element. If it is the same, it will not exist. If it is different, other addresses will be hashed. Therefore, there is a problem of conflict resolution. In this way, the number of actual calls to the equals method will be greatly reduced, To put it mildly, the hashcode method in Java is to map the information related to the object (such as the storage address and field of the object) into a value according to certain rules, which is called the hash value. The following code is the specific implementation of the put method in java.util.hashmap:

The put method is used to add a new element to the HashMap. From the specific implementation of the put method, we will first call the hashcode method to get the hashcode value of the element, and then check whether the hashcode value exists in the table. If so, we will call the equals method to re determine whether the element exists. If so, we will update the value value, otherwise we will add the new element to the HashMap. It can be seen from here that the hashcode method exists to reduce the number of calls to the equals method, so as to improve the program efficiency.

Some friends mistakenly think that by default, hashcode returns the storage address of the object. In fact, this view is not comprehensive. Indeed, some JVMs directly return the storage address of the object during implementation, but this is not the case most of the time. It can only be said that there may be a certain correlation between the storage address. The following is the implementation of generating hash values in the hotspot JVM:

The implementation is located in hotspot / SRC / share / VM / Runtime / synchronizer Cpp file.

Therefore, some people will say, can we judge whether two objects are equal directly according to the hashcode value? Certainly not, because different objects may generate the same hashcode value. Although you can't judge whether two objects are equal according to the hashcode value, you can directly judge whether two objects are unequal according to the hashcode value. If the hashcode values of two objects are unequal, they must be two different objects. If you want to determine whether two objects are really equal, you must pass the equals method.

That is, for two objects, if the result obtained by calling the equals method is true, the hashcode values of the two objects must be equal;

If the result obtained by the equals method is false, the hashcode values of the two objects are not necessarily different;

If the hashcode values of two objects are not equal, the result obtained by the equals method must be false;

If the hashcode values of two objects are equal, the results obtained by the equals method are unknown.

II Equals method and hashcode method

In some cases, when designing a class, the programmer needs to rewrite the equals method, such as the string class. However, it should be noted that when rewriting the equals method, the hashcode method must be rewritten. Why do you say that?

Here is an example:

Here, I only override the equals method, that is, if two people objects have the same name and age, they are considered to be the same person.

The original intention of this code is to output "1", but in fact, it outputs "null". Why? The reason is that you forget to rewrite the hashcode method while rewriting the equals method.

Although two objects with the same logical name and age are determined to be equal by overriding the equals method (similar to the string class), you should know that by default, the hashcode method maps the storage address of the object. It is not surprising that the output result of the above code is "null". The reason is very simple. The object and

System. out. println(hashMap.get(new People("Jack",12))); The new people ("Jack", 12) in this sentence generates two objects, and their storage addresses must be different. The following is the specific implementation of the get method of HashMap:

Therefore, when HashMap performs the get operation, because the obtained hashcdoe values are different (note that the above code may get the same hashcode value in some cases, but this probability is relatively small, because although the storage addresses of the two objects are different, they may also get the same hashcode value), the for loop in the get method will not execute and directly return null.

Therefore, if you want the output result of the above code to be "1", it is very simple. You only need to rewrite the hashcode method so that the equals method and the hashcode method are always logically consistent.

In this way, the output will be "1".

The following paragraph is taken from the Book Effective Java:

During program execution, as long as the information used by the comparison operation of the equals method is not modified, the same object must be called multiple times, and the hashcode method must always return the same integer.

If the two objects are equal according to the equals method comparison, calling the hashcode method of the two objects must return the same integer result.

If the two objects are unequal according to the equals method, the hashcode method does not have to return different integers.

The second and third articles are well understood, but the first one is often ignored. There is a paragraph similar to the first one on page p495 of Java programming ideas:

"The most important factor in designing hashcode() is that whenever you call hashcode() on the same object, it should produce the same value. If you add an object to HashMap with put(), it will produce a hashcdoe value, and use get() If another hashcode value is generated when fetching, the object cannot be obtained. Therefore, if your hashcode method depends on the changeable data in the object, users should be careful, because when the data changes, the hashcode () method will generate a different hash code ".

Here is an example:

The output result of this code is "null". Presumably, everyone should know the reason.

Therefore, when designing the hashcode method and equals method, if the data in the object is changeable, it is best not to rely on this field in the equals method and hashcode method.

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>