First, let's talk about the recommended situation: for example, when your object wants to be put into a set or a map key (non-Hash set and map, such as treeset and treemap ), then you must override the equals () method to ensure uniqueness. Of course, in this case, you do not want to rewrite the hashcode () method, and there is no error. However, for a good programming style, you should rewrite the hashcode () method while rewriting the equals () method.
Then let's talk about the situation where hashcode () must be rewritten:
If your object is to be placed in a Hash Storage set (such as hashset and hashset) or as a key of a hash map (such as hashmap and linkedhashmap, while rewriting the equals () method, you must override the hashcode () method.
Here I want to explain why Sun designers need to design the hashcode method. Maybe you should know when to rewrite it.
The data structure has a data structure that exists to improve the search efficiency-the hash list. The hash list is actually a promotion of the General array concept, because it can directly address the array, therefore, we can access any element of the array in O (1) Time. Thinking has a simple implementation of hashmap in Java. Let's take a look at it and you will understand:
//: Containers/simplehashmap. Java
// A demonstration hashed map.
Import java. util .*;
Import net. mindview. util .*;
Public class simplehashmap <K, V> extends abstractmap <K, V> {
// Choose a prime number for the hash table
// Size, to achieve a uniform distribution:
Static final int size = 997;
// You can't have a physical array of generics,
// But you can upcast to one:
@ Suppresswarnings ("unchecked ")
Counter list <mapentry <K, V> [] buckets =
New shortlist [size]; // each item in the list array is a list, and the array subscript is the return value of the hashcode method, which is obtained through the hash function, which is equivalent to the keyword of the hash list, it also represents the keywords of each object. (A New Generic Array cannot be displayed, but you can reference A New Generic Array. If necessary, you can convert an ordinary array to a generic array ).
Public v put (K key, V value) {// put this key pair value into hashmap.
V oldvalue = NULL;
Int Index = math. ABS (key. hashcode () % size; // here, a keyword is obtained through processing the return value of hashcode by the hash function. It represents the position of the object in the array and is both an array subscript.
If (buckets [Index] = NULL)
Buckets [Index] = new partition list <mapentry <K, V> (); // if this is the first time the array subscript is hashed, a new partition list is generated, you can see that mapentry <K, V> keys and values are saved in it.
Your list <mapentry <K, V> bucket = buckets [Index]; // assign the value of your list to a bucket. Then, you can operate on this bucket directly.
Mapentry <K, V> pair = new mapentry <K, V> (Key, value );
Boolean found = false;
Listiterator <mapentry <K, V> it = bucket. listiterator ();
While (it. hasnext ()){
Mapentry <K, V> ipair = it. Next ();
If (ipair. getkey (). Equals (key) {// if the same key value already exists, update the value.
Oldvalue = ipair. getvalue ();
It. Set (pair); // replace old with new
Found = true;
Break;
}
}
If (! Found)
Buckets [Index]. Add (pair); // if it is a new key value, directly add it to this sort list.
Return oldvalue;
}
Public v get (Object key) {// see how hashmap uses the hashcode method to quickly locate the key value.
Int Index = math. ABS (key. hashcode () % size; [color = Red] // generates an array subscript in the same way as the put method, because it is stored in this place when I save it, then, access buckets [Index] directly. [/Color]
If (buckets [Index] = NULL) return NULL; // directly access the list of objects under the array. If it is null, return.
For (mapentry <K, V> ipair: buckets [Index]) // Why should we use the sorted list? Because the hash code generated by the hashcode method cannot completely determine an object, that is to say, it will "collide" with other objects, that is, hash to the same Array subscript. The way to solve this problem is to define a list to save them, but in this list, we must ensure that the equals method can be used to determine the identity of an object. That is why many people say that hashcode () is equal, equals () is not necessarily equal, and equals () is equal to two objects, hashcode () must be equal. Therefore, linear search is directly performed on the sorted list.
If (ipair. getkey (). Equals (key ))
Return ipair. getvalue ();
Return NULL;
}
Public set <map. Entry <K, V> entryset (){
Set <map. Entry <K, V> set = new hashset <map. Entry <K, V> ();
For (catalog list <mapentry <K, V> Bucket: buckets ){
If (bucket = NULL) continue;
For (mapentry <K, V> mpair: bucket)
Set. Add (mpair );
}
Return set;
}
Public static void main (string [] ARGs ){
Simplehashmap <string, string> M =
New simplehashmap <string, string> ();
M. putall (countries. capitals (25 ));
System. Out. println (m );
System. Out. println (M. Get ("Eritrea "));
System. Out. println (M. entryset ());
}
}/* Output:
{Cameroon = Yaounde, Congo = Brazzaville, Chad = N' Djamena, Cote d' ivoir (Ivory Coast) = California, Central African Republic = Bangui, Guinea = Conakry, Botswana = Gaberone, bissau = Bissau, Egypt = Cairo, Angola = Luanda, Burkina Faso = California, Eritrea = Asmara, the Gambia = Banjul, Kenya = Nairobi, Gabon = Libreville, Cape Verde = Praia, algeria = Algiers, Comoros = Moroni, Equatorial Guinea = Malabo, Burundi = Beijing, Benin = Porto-Novo, Bulgaria = Sofia, Ghana = Accra, region = dijiboti, region = Addis Ababa}
Asmara
[Cameroon = Yaounde, Congo = Brazzaville, Chad = N' Djamena, Cote d' ivoir (Ivory Coast) = California, Central African Republic = Bangui, Guinea = Conakry, Botswana = Gaberone, bissau = Bissau, Egypt = Cairo, Angola = Luanda, Burkina Faso = California, Eritrea = Asmara, the Gambia = Banjul, Kenya = Nairobi, Gabon = Libreville, Cape Verde = Praia, algeria = Algiers, Comoros = Moroni, Equatorial Guinea = Malabo, Burundi = Beijing, Benin = Porto-Novo, Bulgaria = Sofia, Ghana = Accra, region = dijiboti, region = Addis Ababa
How? Now we should know the role of the hashcode method, which is used to improve efficiency. There is a saying: Hashing for speed. Because the hash set and map are based on the hashcode method to find objects, you must overwrite the hashcode method when using these classes, instead of the hash set and map, for example, treeset and treemap, they only need the equals method to uniquely identify the object. In this case, it must be clear.
Does the hashcode method need to be rewritten after the equals method of the object is rewritten?