Summary of hashCode and equals methods in Java

  • 2020-04-01 02:24:01
  • OfStack

First, to understand what hashCode does, you have to know about collections in Java.

In general, there are two types of collections in Java, a List and a Set. The elements in the former set are ordered and can be repeated. The latter element is unordered, but the element is not repeatable.

So here's the big question: what does it take to make sure that two elements are not duplicated? So that's the object.equals method. However, if you check every element you add, then when there are a lot of elements, the number of times that elements are added to the collection will be very large. That is, if there are already 1000 elements in the collection, it will call equals 1000 times when the 1001st element is added to the collection. This obviously reduces efficiency considerably.    

Therefore, Java adopts the principle of hash table. A Hash is actually a person's name, named after him because he came up with the idea of a Hash algorithm. Hash algorithms, also known as hash algorithms, assign data to an address directly according to a particular algorithm. For starters, the hashCode method actually returns the physical address of the object's storage (which may not be).    

This way, when the collection adds a new element, the hashCode method for that element is called first, and all of a sudden it is positioned where it should be physically. If there are no elements in this location, it can be stored in this location without any comparison. If there is already an element in this location, its equals method is called to compare with the new element. If it is the same, it will not be saved. If it is different, it will hash other addresses. So there's a conflict resolution issue here. This reduces the number of actual calls to equals to almost one or two.  

So, the eqauls and hashCode methods are specified in Java as follows:

1. If two objects are the same, their hashCode values must be the same;

2. If two objects have the same hashCode, they are not necessarily the same.    

Of course you can go against the rules, but you'll find that the same object can appear in the Set Set. At the same time, the efficiency of adding new elements is greatly reduced.

Hashcode is a method used to determine whether two objects are equal. So you say, isn't there an equals method? Yes, both methods are used to determine whether two objects are equal. But there is a difference. In general, the equals method is called for the user. If you want to determine if two objects are equal, you can override the equals method and call it in your code to determine if they are equal. In simple terms, the equals method is primarily used to determine whether two objects are equal, either visually or in terms of content.

For example, if there is a student class whose attributes are only name and gender, then we can assume that as long as the name and gender are equal, then these two objects are equal. The hashcode method is usually not called by the user. For example, in the hashmap, since the key cannot be repeated, he determines the hashcode method when determining whether the key is repeated, and equals method is also used. You can't repeat equals and hashcode as long as you have one not equal! So hashcode is simply the code of an object, like md5 in a file, and it's different from equals because it returns an int, which is not intuitive. We usually override hashcode as well as equals to make their logic consistent. So for example, again, if the name and the gender are equal even if the two objects are equal, then the method of hashcode is going to return the hashcode value of the name plus the hashcode value of the gender, so that logically they're consistent. To physically determine whether two objects are equal, use ==.

In the Java language, the use of the equals() and hashCode() functions is so tightly coupled that if you design one, you design the other. In most cases, these two functions are not considered, but simply use their default design. However, in some cases, these functions are best designed by themselves to ensure that the entire program runs properly. Most commonly, when an object is added to a collection object, the two functions must be designed themselves. A more refined definition is: if you want the one object into another collection of object B, or use the object is to find A meta object in A collection of B in the location of the keys, and support to accommodate, delete the meta object in the object B such collection operation, so the equals () and hashCode () function to define their own developers. Otherwise, these two functions don't need to be defined.

The equals () :

It is used to compare two objects, to compare the contents of the object, and, of course, to compare the reference values of the object. What is a comparison of object reference values? We all know that the value of a reference variable is actually a number, which can be thought of as a code for identifying different objects. A comparison of two objects is a comparison of two Numbers and two symbols. This comparison is an implicit Object comparison, which is already designed in Object. So you don't have to rewrite it yourself and waste unnecessary time.

The comparison of object contents is the real purpose of designing equals(), and the Java language has the following requirements for equals(), which must be followed. Otherwise, you shouldn't waste your time:

The & # 8226; Symmetry: If x.quals (y) returns true, then y.quals (x) should also return true.

The & # 8226; Reflective: X.equals (x) must return "true".

The & # 8226; Analogy: If x.quals (y) returns true, and y.quals (z) returns true, then z.quals (x) should also return true.

The & # 8226; And 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.

The & # 8226; In any case , x.exquals (null), always returns "false"; X.equals (objects of a different type than x) always returns "false".

HashCode () :
This function returns an integer code for the hirsch operation, not to be confused with the code for the reference variable. The latter is not only a code name but also has the ability to find the location of an image in memory. The value returned by hashCode() is used to classify the object's location in some particular collection object. These objects are HashMap, Hashtable, HashSet, and so on. This function and the equals() function above must be designed to assist HashMap, Hashtable, HashSet, and so on in searching and locating the large number of objects they have collected.

How exactly do these collection objects work, imagine that each meta-object hashCode is the code for a bin, and by code, each meta-object is placed in the corresponding bin according to the code provided by hashCode(). All add up to a HashSet box, a HashMap, or Hashtable object, we need to find a meta object, read the code, it is the hashCode () returns the integer value, so that we find it in the box, and then in the box, take out every a meta object and comparing the object we are looking for, if two objects are equal, the contents of our search ends. This operation requires two important pieces of information, the hashCode() of the object, and the result of a comparison of the object's contents.

The relationship between the return value of hashCode() and equals() is as follows:

The & # 8226; If x.esquals (y) returns "true", then the hashCode() of x and y must be equal.

The & # 8226; If x.esquals (y) returns "false", then the hashCode() of x and y may or may not be equal.

The reason why these two rules are the case is actually quite simple. Take a HashSet, for example. A HashSet can have one or more boxes, and in the same box can have one or more unique meta-objects (what a HashSet must contain must be unique meta-objects). This example shows that a meta-object can have the same hashCode as a different meta-object. But a meta-object can only be equal to a meta-object that has the same content. So these two rules have to be true.

What to notice about designing these two functions:
If you are designing an object type that is not used for collection objects, there is no need to design the handling of these two functions yourself. This is the correct object-oriented design method, any user can not use the function, do not design first, so as not to cause trouble in the future function extension.

If you want to be creative in your design and don't follow the above two sets of rules, you are advised not to do so. I haven't met a developer who has told me to design these two functions in violation of the above two rules, and I've encountered these violations as design errors.

When an object type is a meta-object for a collection object, the object should have its own design for handling equals(), and/or hashCode(), and follow both of the above principles. Equals () checks to see if null and equals are of the same type. The purpose of looking up the same type is to avoid exceptions like ClassCastException being thrown out. Checking null is to avoid throwing nullpointerexceptions.

If you have too much data in your object, the two functions equals() and hashCode() will become inefficient. If you have data in an object that cannot be serialized, equals() is likely to have errors in the operation. Imagine an object x whose integer data is transient (cannot be serialized as a binary data stream). However, both equals() and hashCode() rely on this integer data, so is this object the same before and after serialization? The answer is no. Because the integer data before serialization is valid data, the value of the integer data is not stored after serialization, and the state of the two objects (before and after serialization) is different after the binary data flow is changed into an object. This is also important.

Knowing these things can help you:

1. Better design and development.

2. Better test case development.

3. Make sure the interviewer is satisfied with your knowledge during the interview.


Related articles: