HashCode ();
It is a local method, and its implementation is related to the local machine. Here we temporarily think that the physical location of the Object Storage is returned (actually not, it is easy to understand here ). When we add an element to a set, the set will first call the hashCode method, so that we can directly locate the location it stores. If there are no other elements, it will be saved directly. If an element already exists, call the equals method to match whether the two elements are the same. If they are the same, they are not saved, different columns are hashed to other locations (For details, refer to (Java tutorial () ----- HashMap )). In this way, when we store a large number of elements, we can greatly reduce the number of calls to the equals () method, greatly improving the efficiency.
SoThe role of hashCode in the preceding example is domain search.(Find the location of an object in the collection area ). HashCode can divide a set into several regions. Each object can calculate its hash code. It can group the hash code. Each group corresponds to a storage region, the region where the object is stored can be determined based on the hash code of an object, which greatly reduces the number of query matching elements and improves the query efficiency.
The importance of hashCode for an object
Is hashCode important? It is not important. It is cumbersome for List sets and arrays, but it becomes very important for HashMap, HashSet, and HashTable. Therefore, you must pay attention to hashCode when using HashMap, HashSet, and HashTable. For an object, its hashCode process is a simple Hash algorithm. Its implementation process plays a very important role in implementing the object access process.
Previously, LZ mentioned two data structures, HashMap and HashTable. Although they have several differences, their implementation principles are the same, here I take HashTable as an example to illustrate the importance of hashCode for an object.
An object is bound to have several attributes. How to Select attributes for hashed testing a person's design ability. If we hash all the attributes, this will be a bad design, because the hashCode method of the object is not called all the time. If too many attributes are involved in the hash, the required operand time will be greatly increased, which will seriously affect the program performance. However, if a small number of objects are involved in the hash, the diversity of the hash will be weakened, resulting in a large number of hash "conflicts", in addition to being unable to make good use of space, to some extent, the query efficiency of objects is also affected. In fact, the two are a contradiction, and the diversity of hash will reduce the performance.
LZ has no experience in designing the hashCode of objects. A solution was found on the Internet: Set a cache identifier to cache the current hash code. The calculation is performed only when the object involved in the hash changes, otherwise, the cached hashCode can be called to greatly improve the performance.
Run the following code to calculate the index position of an object in the table [] array in HashTable:
index = (hash & 0x7FFFFFFF) % tab.length;
Why & 0x7FFFFFFF? Because the hashCode of some objects may be negative, performing operations with 0x7FFFFFFF can ensure that the index is a positive number. In this step, I can directly locate the location of an object, so theoretically we can use hashCode to directly locate the location in the object's hash list, but why is there a key-value pair that uses the hashCode of the key to store data instead of directly storing the value? This is the most important issue related to HashTable performance: Hash conflict!
We know that the conflict is generated because different objects produce the same hash code. If we design an object hash code, we can ensure that 99.999999999% of the hash code is not repeated, however, you cannot avoid an absolute and almost impossible conflict. We know that hashcode returns an int, and its value is only within the int range. What if the data we store exceeds the int range? In this way, two identical indexes will be generated, and two objects will be stored at the index position, so we can use the key itself for judgment. Therefore, for objects with indexes, there are multiple objects at the index position. We must rely on the hashCode of the key and the key itself for differentiation.
HashCode and equals
In Java, the implementation of hashCode is always accompanied by equals. They work closely together. If you design one of them, you need to design another one. Of course, in most cases, these two methods do not need to be considered. Using the default method directly can help us solve many problems. However, in some cases, we must implement it by ourselves to ensure better program operation.
For equals, we must follow the following rules:
Symmetry: If x. equals (y) returns "true", then y. equals (x) returns "true ".
Reflex: x. equals (x) must return "true ".
Analogy: If x. equals (y) returns "true", and y. equals (z) returns "true", then z. equals (x) should also return "true ".
Consistency: If x. equals (y) returns "true", as long as the content of x and y remains unchanged, No matter you repeat x. "true" is returned for the number of equals (y) times ".
In any case, x. equals (null) always returns "false"; x. equals (and x objects of different types) always returns "false ".
For hashCode, we should follow the following rules:
1. during the execution of an application, if the information used for the equals Method Comparison of an object is not modified, the hashCode method is called for this object multiple times, it must always return the same integer.
2. If the two objects are equal according to the equals (Object o) method, the hashCode method of any of the two objects must produce the same integer result.
3. If the two objects are inconsistent according to the equals (Object o) method, the hashCode method of any of the two objects is called and different integer results are not required. However, if it can be different, it may improve the performance of the hash.
As for the relationship between the two, we only need to remember the following:
If x. equals (y) returns "true", the hashCode () of x and y must be equal.
If x. equals (y) returns "false", the hashCode () of x and y may be equal or different.
After clarifying the relationship above, we will know how they work together. First look:
Sex; PRIME = 37 age ,. age =. sex =. name = "Call the hashCode method ........... "hashResult = 1 = (hashResult + Integer. valueOf (age ). hashCode () + Integer. valueOf (sex ). hashCode () * = PRIME * hashResult + (name = )? 0 "name:" + name + "hashCode:" + "Call the equals method..." (obj = (obj. getClass ()! = (GetAge ()! = Person. getAge () | getSex ()! = (GetName ()! = (! (Person! =
This Bean is a standard Java Bean and implements the hashCode and equals methods again.
Main <Person> set = HashSet <Person> = Person (11, 1, "Zhang San" = Person (12, 1, "Li Si" = Person (11, 1, "Zhang San" = Person (11, 1, "Li Si" System. out. println ("p1 = p3? : "+ (P1 =" p1.equals (p3 )? : "+" ----------------------- Split line -------------------------- "" set. size () = "+
The running result is as follows:
It can be seen that the program calls the hashCode method four times, and the equals method one time, the set length is only 3. The process of running the add method is completely in line with the process between the two.
For more information, see:
>>>>>>>>> Java (13) ------ equals ()
>>>>>>>>> Java (Article 2 and 3) ------ HashMap
>>>>>>>>>> Java (Article 2 and 4) ------ HashSet
>>>>>>>>> Java (Article 2 and 5) ------ HashTable