Preface
As we all know, Java.lang.Object has a hashCode() and an equals() method, which play an important role in software design. Rewrite these two methods in some classes to accomplish some important functions.
1. Why use hashCode()?
The elements in the set set are disordered and unrepeatable. So what is the basis for judging whether two elements are repeated?
Some people say: Object.equal() is of course used to compare whether objects are equal. However, there are a large number of objects in the Set, and the number of comparisons of object elements added to the set set will gradually increase, greatly reducing the efficiency of the program operation. Java uses hashing algorithm (also called hashing algorithm) to solve this problem. The object (or data) is directly mapped to an address according to a specific algorithm, and the access efficiency of the object is greatly improved.
In this way, when a set containing a large number of elements needs to add an element (object), first call the hashCode() of this element, and you can position the actual storage location of this element at once. If there is no element at this position, it means that this object is stored in the collection Set for the first time, and the object is stored directly at this position; if there is an object at this position, call equal() to see if the two objects are equal. If the same is true, discard the element and do not exist. If it is not equal, hash to other addresses.
This is also the reason why when the set set stores object type data, it is necessary to not only rewrite the hashCode() method of the object but also rewrite the equals() method.
2. HOW use hashCode()?
The relationship between the return value of hashCode() and equals()
Here is an example. In actual software development, it is best to rewrite these two methods.
public class Employee { int employeeId; String name; @Override public boolean equals(Object obj) { if(obj==this) return true; Employee emp=(Employee)obj; if(employeeId.equals(emp.getEmployeeId()) && name==emp.getName()) return true; return false; } @Override public int hashCode() { int hash = 1; hash = hash * 17 + employeeId; hash = hash * 31 + name.hashCode(); return hash; }}The equals() and hashCode() methods are used to compare in the same class, especially when storing the same class object in the container such as set to store objects in the same class.
Here we first need to understand a problem:
Two objects with equals() equals, hashcode() must be equal, and two objects with equals() not equals, cannot prove that their hashcode() is not equal. In other words, for two objects whose equals() method is not equal, hashCode() may be equal.
Here hashCode is like the index of each character in the dictionary, and equals() is like comparing different words under the same character in the dictionary. Just like in the dictionary, searching for the two words "self" and "spontaneous" under the word "self" in the dictionary, if equals() is used to determine the equality of the words query, it is the same word. For example, the two words compared by equals() are "self", then the values obtained by hashCode() method must be equal at this time; if equals() method compares the words "self" and "spontaneous", then the result is that you don't want to wait, but both of these words belong to the words "self" and so when searching for indexes, that is, hashCode() is the same. If equals() compares the words "self" and "they", then the results are also different, and the results obtained by hashCode() are also different at this time.
Conversely: hashcode() is different, and equals() can be introduced; hashcode() is equal, equals() may be equal or may not be equal.
In the object class, the hashcode() method is a local method, which returns the address value of the object. The equals() method in the object class also compares the address values of the two objects. If equals() is equal, it means that the address values of the two objects are also equal. Of course, hashcode() is equal.
Since equals is more accurate to compare equal elements, why use hashCode( ) method?
Because the hash algorithm provides high efficiency in finding elements, if you want to find whether a collection contains an object, how to write the approximate program code?
You usually take out each element one by one to compare with the object you are looking for. When you find that the result of the equals method comparison between an element and the object you are looking for, stop searching and return positive information. Otherwise, return negative information. If there are many elements in a collection, such as 10,000 elements and do not contain the object you are looking for, it means that your program needs to take out 10,000 elements from the collection and compare one by one to get a conclusion.
The Object class defines a hashCode() method to return the hash code of each Java object. When looking for an object from the HashSet collection, the Java system first calls the hashCode() method of the object to obtain the hash code table of the object, and then finds the corresponding storage area based on the hash, and finally obtains each element in the storage area and compares it with the object for equals method. In this way, you can get the conclusion without traversing all elements in the collection. It can be seen that the HashSet collection has good object retrieval performance.
However, the efficiency of storing objects in the HashSet collection is relatively low, because when adding an object to the HashSet collection, the hash code of the object must be calculated first and the storage location of the object in the collection is determined based on this hash code. In order to ensure that the instance objects of a class can be stored normally in HashSet, the results of the two instance objects of this class must be equal when compared with the equals() method are equal; that is, if the result of obj1.equals(obj2) is true, then the result of the following expression must also be true:obj1.hashCode() == obj2.hashCode() .
In other words: when we rewrite an object's equals method, we must rewrite its hashCode method. If we do not rewrite its hashCode method, the hashCode method in the Object object always returns the hash address of an object, and this address is never equal. So even if the equals method is rewritten at this time, there will be no specific effect, because if the hashCode method does not want to wait, it will not call the equals method for comparison, so it is meaningless.
Most data structures use the equals method to determine whether they contain an element, for example:
List<String> list = Arrays.asList("a", "b", "c");boolean contains = list.contains("b"); This variable contains result is true because, although "b" is different instances (in addition, string residency is ignored), they are equal.
They use a quick way to compare (reduce potential instance equality) instead of comparing each element contained in the instance. Quick comparison only requires comparing the following aspects:
Shortcut comparison means that by comparing hash values, it can replace an instance with an integer value. Instances with the same hash code are not necessarily equal, but instances with equality must have the same hash value. (or should have, we'll discuss this soon) These data structures are often named by this technique, and they can be identified by Hash, among which HashMap is the most famous representative.
They usually work like this:
When adding an element, its hash code is used to calculate the index of the internal array (that is, the so-called bucket)
If yes, unequal elements have the same hash code, they end up on the same bucket and bundled together, for example by adding to the list.
When an instance performs contains operations, its hash code will be used to calculate the bucket value (index value), and the instance will be compared only when elements exist on the corresponding index value.
Therefore equals, hashCode is defined in the Object class.
If hashCode is used as a shortcut to determine equality, then there is only one thing we should care about: equal objects should have the same hashcode, which is why if we override the equals method, we have to create a hashCode implementation that matches it!
Otherwise equal objects may not have the same hash code, because they will call the default implementation of Object's.
Quote from official documents
hashCode general convention:
When calling the same object running in a Java application, the hashCode method must always return the same integer. This integer does not need to be consistent across different Java applications. According to equals(Object) method, if two objects are equal, the two objects call the hashCode method must produce the same result.
According to equals(Object) method, if the two objects are not equal, then calling the hashCode method does not necessarily produce different integer results. However, programmers should realize that producing different integer results for unequal objects will likely improve the performance of the hash table.
HashCode implementation
Here is a simple implementation of person.hashcode() :
@Overridepublic int hashCode() { return Objects.hash(firstName, lastName);}person's calculates hash code by combining multiple fields. All are calculated by Object's hash function.
Select a field
But which fields are related? The requirements will help us answer this question:
If an equal object must have the same hash code, the computed hash code should not include any fields that are not used for equality checks. (Otherwise, the two objects are just that these fields are different but they may still be equal, but the hash codes of the two objects will be different at this time.) So the subset of the fields used when the hash group fields should be equal. The same fields are used by default, but there are some details to consider.
Summarize
We understand that calculating hash code is to compress an equal integer value: equal objects must have the same hash code, and for performance considerations, it is best to share the same hash code as few as possible unequal objects.
This means that if the equals method is rewritten, then the hashCode method must be rewritten.
When implementing hashCode uses the same fields as used in equals (or a subset of fields used in equals)
It is best not to include mutable fields. Do not consider calling hashCode for collections. If there is no special input specific mode, try to use a general hash algorithm.
Okay, the above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.