Why you must override the Hashcode method while overriding the Equals method _java

Source: Internet
Author: User

We all know that the Java language is fully object-oriented, and in Java, all objects are inherited from the object class.
The Equals method compares the addresses of two objects to the address, Hashcode is a local method, and returns the object address value. There are two methods equals and Hashcode in the Ojbect class, both of which are used to compare the equality of two objects.

Why rewrite the Equals method must also override the Hashcode method?

You can understand this: rewrite the Equals method, the same business logic to judge the object is changed, class designers do not want to compare the memory address to compare two objects are equal, and the Hashcode method to continue to compare the address to do not have any meaning, simply follow together to change it.

Another reason comes from the collection. Say it slowly below ~

As an example:

In school, it is through the study number to judge whether this person.

The following code in the situation for enrollment, school number 123 was assigned to the students Tom, school number 456 was assigned to students Jerry, school number 123 was assigned to Lily. And in the process of enrollment is not the same as the number of students should appear.

You cannot add duplicate objects based on the scenario requirements, which can be implemented by HashSet.

public class Test {public
static void Main (string[] args) {
Student stu = new Student (123, "Tom");
hashset<student> set = new Hashset<> ();
Set.add (Stu);
Set.add (New Student (456, "Jerry"));
Set.add (New Student (123, "Lily"));
Iterator<student> iterator = Set.iterator ();
while (Iterator.hasnext ()) {
Student Student = Iterator.next (); 
System.out.println (Student.getstunum () + "---" + student.getname ());
}
}
;
Class Student {
private int stunum;
private String name;
Public Student (int stunum,string name) {
this.stunum = stunum;
this.name = name;
public int Getstunum () {return
stunum;
}
Public String GetName () {return
name;
}
@Override public
boolean equals (Object obj) {
if (this==obj) return
true;
if (obj instanceof Student) {
if (this.getstunum () = = ((Student) obj). Getstunum ()) return
true;
}
return false;
}

The output is:

123---Lily.
456---Jerry.
123---Tom.

According to the output, we found that the designation of school number 123 to Lily was successful. What's wrong?

Let's take a look at HashSet's Add method:

Public boolean Add (E. e) {return
map.put (E, PRESENT) ==null;
}

In fact, HashSet is implemented through HASHMAP, which we traced to the HashMap put method:

Public V-Put (K key, V value) {
if (table = = empty_table) {
inflatetable (threshold);
}
if (key = = null) return
Putfornullkey (value);
int hash = hash (key);
int i = indexfor (hash, table.length);
for (entry<k,v> e = table[i]; e!= null; e = e.next) {
Object K;
if (E.hash = = Hash && ((k = e.key) = = Key | | key.equals (k))) {
V oldValue = e.value;
E.value = value;
E.recordaccess (this);
Return OldValue
}
}
modcount++;
AddEntry (hash, key, value, I);
return null;

1. According to Key, that is hashset to add object, get Hashcode, by hashcode do special location operation get hash code;

2. Using the hash code location to find the array subscript, get the chain of the first list;

3. Traverse the list to find there is no the same key, judged on the basis of E.hash = = Hash && (k = e.key) = = Key | | key.equals (k)). In Add Lily, because the Equals method was rewritten, the second condition should be true when traversing to Tom, but because the Hashcode method still uses the parent class, Tom and Lily's hashcode is different from the hash code, the first one The part is false. Here the two objects are different so hashset add Lily success.

The reason for this is that there is no rewrite of the Hashcode method, the following is modified:

public class Test {public
static void Main (string[] args) {
Student stu = new Student (123, "Tom");
hashset<student> set = new Hashset<> ();
Set.add (Stu);
Set.add (New Student (456, "Jerry"));
Set.add (New Student (123, "Lily"));
Iterator<student> iterator = Set.iterator ();
while (Iterator.hasnext ()) {
Student Student = Iterator.next (); 
System.out.println (Student.getstunum () + "---" + student.getname ());
}
}
;
Class Student {
private int stunum;
private String name;
Public Student (int stunum,string name) {
this.stunum = stunum;
this.name = name;
public int Getstunum () {return
stunum;
}
Public String GetName () {return
name;
}
@Override public
boolean equals (Object obj) {
if (this==obj) return
true;
if (obj instanceof Student) {
if (this.getstunum () = = ((Student) obj). Getstunum ()) return
true;
}
return false;
}
@Override public
int hashcode () {return
getstunum ();
}

Output:

456---Jerry.
123---Tom.

Rewrite the Hashcode method to return to the school number. OK, that's it.

Someone might be surprised, e.hash = = Hash && ((k = e.key) = = Key | | key.equals (k)) This condition is not a bit complicated, I feel that only use the Equals method on the Ah, why should be superfluous to judge the has What about Hcode?

Because in the HashMap of the chain list structure to traverse the judgment, in particular case overrides the Equals method compares the object to be equal the business logic to be more complex, the circulation down is affects the search efficiency. So here the hashcode judgment in front, as long as the hashcode is not equal to play, no longer to call the complex equals. Improve the efficiency of HASHMAP in many ways.

So the rewrite Hashcode method is to allow us to use the HASHMAP and other collection classes normally, because the HASHMAP judge whether the object is equal must compare hashcode and use equals. And this realization is to improve the efficiency of HASHMAP.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.