Details of hashcode () and equals () in Java)

Source: Internet
Author: User

Original post address http://www.javaeye.com/topic/257191

 

This afternoon I studied the hashcode () and equals () methods for half a day, and finally got a little bit of understanding. I will write it down and share it with you (zhaoxudong
21.36 ).

1. First, the equals () and hashcode () methods are inherited from the object class.

The equals () method is defined in the object class as follows:

Public Boolean equals (Object OBJ ){

Return (this = OBJ );

}

It is obvious that the address values of the two objects are compared (that is, whether the reference is the same ). But we must be clear that when the string
, Math, integer, double .... When using the equals () method, these encapsulation classes already overwrite the equals () method of the object class. Ratio
For example, in the string class:

Public Boolean equals (Object anobject ){

If (this = anobject ){

Return true;

}

If (anobject instanceof string ){

String anotherstring = (string) anobject;

Int n = count;

If (n = anotherstring. Count ){

Char V1 [] = value;

Char V2 [] = anotherstring. value;

Int I = offset;

Int J = anotherstring. offset;

While (n --! = 0 ){

If (V1 [I ++]! = V2 [J ++])

Return false;

}

Return true;

}

}

Return false;

}

Obviously, this is the content comparison, but it is no longer the address comparison. And so on, double, integer, math .... And so on.
Equals () method, so as to compare the content. Of course, the basic type is to compare values. There is nothing to say about it.

We should also note that the requirements of the Java language for equals () are as follows, which must be followed:

• 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) also returns Yes
"True ".


There is also 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 ".

The above five points are the rules that must be followed when the equals () method is rewritten. If any violation occurs, unexpected results will be observed.

2. The second is the hashcode () method, which is defined in the object class as follows:

Public native int hashcode ();

The description is a local method, which is implemented based on local machines. Of course, we can overwrite the hashcode () method in the class we write, such as string,
Integer, double .... And so on. For example, the hashcode () method defined in the string class is as follows:

Public int hashcode (){

Int H = hash;

If (H = 0 ){

Int off = offset;

Char Val [] = value;

Int Len = count;

For (INT I = 0; I <Len; I ++ ){

H = 31 * H + val [Off ++];

}

Hash = h;

}

Return h;

}

Explain this program (written in the string API ):

S [0] * 31 ^ (n-1) + s [1] * 31 ^ (n-2) +... + s [n-1]

The Int algorithm is used. Here, s [I] is the I character of the string, n is the length of the string, and ^ represents the power. (The hash code of the Null String is 0 .)

3. here we need to understand the following question:

Two objects with equal equals () must have equal hashcode;

Equals () is not equal to two objects, but it cannot prove that their hashcode () is not equal. In other words, the equals () method is not equal to two pairs
Like, hashcode () may be equal. (In my understanding, the hash code is generated in a conflict ).

In turn, hashcode () is not equal. Equals () is always available. hashcode () is equal. Equals () may be equal or not. Explanation
The scope of use at. I understand that it can be used in objects, strings, and other classes. In the object class, the hashcode () method is a local method and returns the object's
The address value. The equals () method in the object class compares the address values of the two objects. If equals () is equal, the address values of the two objects are equal. Of course
Hashcode () is equal. In the string class, equals () returns a comparison of the content of two objects. When the content of two objects is equal,

The hashcode () method analyzes the code based on the string class rewriting (analyzed in point 2nd). You can also know that the returned results of hashcode () are equal. This class
We can know that the overwritten equals () and hashcode () methods in integer and double encapsulation classes are also suitable for this principle. Of course, it has not been rewritten.
Class. This principle is also observed after the equals () and hashcode () Methods of the object class are inherited.

4. When talking about hashcode () and equals (), we can't help but talk about the usage of hashset, hashmap, and hashtable. Please refer
Analysis:

Hashset inherits the set interface and implements the collection interface. This is a hierarchical relationship. So what principle does hashset use to access objects?

Repeated objects are not allowed in hashset, And the element location is also unknown. In hashset, how does one determine whether the elements are repeated? This is the key to the problem.
The one-afternoon query verification has finally gained some inspiration. I would like to share with you that in the Java Collection, the rule for determining whether two objects are equal is:

1), judge whether the hashcode of the two objects is equal

If they are not equal, the two objects are considered not equal.

If equal, transfer 2)

(This is only required to improve storage efficiency. In theory, it is not acceptable. However, if it is not, the actual usage of the aging rate will be greatly reduced. Therefore, we need it here. Important points
.)

2) determine whether two objects are equal using the equals operation

If they are not equal, the two objects are considered not equal.

If the two objects are equal, equals () is the key to determining whether the two objects are equal)

Why are there two principles? Can't I use the first one? No, because as mentioned earlier, the equals () method may also differ when hashcode () is equal, so 2nd must be used.
To ensure that non-repeating elements are added.

For example, the following code:

Public static void main (string ARGs []) {

String S1 = new string ("zhaoxudong ");

String S2 = new string ("zhaoxudong ");

System. Out. println (S1 = S2); // false

System. Out. println (s1.equals (S2); // true

System. Out. println (s1.hashcode (); // s1.hashcode () equals s2.hashcode ()

System. Out. println (s2.hashcode ());

Set hashset = new hashset ();

Hashset. Add (S1 );

Hashset. Add (S2 );

/* In essence, when adding S1 and S2, we can use the two principles mentioned above to understand that hashset considers S1 and S2 to be equal and is adding duplicate elements, so S2 overwrites
S1 ;*/

Iterator it = hashset. iterator ();

While (it. hasnext ())

{

System. Out. println (it. Next ());

}

At last, only a "zhaoxudong" is printed during the while loop ".

The output result is: false.

True

-967303459

-967303459

This is because the string class has overwritten the equals () method and hashcode () method. Therefore, according to the above article 1.2, hashset considers that
They are equal objects and are added repeatedly.

But look at the following program:

Import java. util .*;

Public class hashsettest

{

Public static void main (string [] ARGs)

{

Hashset HS = new hashset ();

HS. Add (new student (1, "zhangsan "));

HS. Add (new student (2, "Lisi "));

HS. Add (new student (3, "wangwu "));

HS. Add (new student (1, "zhangsan "));

 

Iterator it = HS. iterator ();

While (it. hasnext ())

{

System. Out. println (it. Next ());

}

}

}

Class student

{

Int num;

String name;

Student (INT num, string name)

{

This. num = num;

This. Name = Name;

}

Public String tostring ()

{

Return num + ":" + name;

}

}

Output result:

1: zhangsan

1: zhangsan

3: wangwu

2: Lisi

The problem arises. Why does hashset add equal elements? Is this contrary to the hashset principle? The answer is: no

Because the new
When student (1, "zhangsan") objects are compared, different hash code values are generated. Therefore, hashset treats them as different objects.
The value returned by the equals () method does not have to be explained ). So why does it generate different hash code values? When comparing S1 and S2, we didn't generate the same hash code.
? The reason is that the student class we write does not repeat the hashcode () and equals () methods. Therefore, during comparison
The hashcode () method. You can remember what the hashcode () method in the object class compares !!

It is a local method that compares the object address (reference address) and creates an object using the new method, of course, the two generated objects are different (you can understand this ...), Cause
The result is that the values returned by the hashcode () of the two objects are different. Therefore, according to the first criterion, hashset treats them as different objects, and naturally does not use the second criterion.
Determined. So how can we solve this problem ??

The answer is: Re-hashcode () and equals () methods in the student class.

For example:

Class student

{

Int num;

String name;

Student (INT num, string name)

{

This. num = num;

This. Name = Name;

}

Public int hashcode ()

{

Return num * name. hashcode ();

}

Public Boolean equals (Object O)

{

Student s = (student) O;

Return num = S. Num & name. Equals (S. Name );

}

Public String tostring ()

{

Return num + ":" + name;

}

}

Based on the override method, even if the new
Student (1, "zhangsan"), when we get the object's hash code, according to the override method hashcode (), the obtained hash code must be the same (this should not
If you have any questions ).

Of course, based on the equals () method, we can also judge that it is the same. So they are treated as repeated elements when added to the hashset set. So when I run the modified program
The running result is:

1: zhangsan

3: wangwu

2: Lisi

We can see that the duplicate element problem has been eliminated.

In the pojo class of hibernate, the problem of re-equals () and hashcode () is as follows:

1) the focus is on equals. Rewriting hashcode is only a technical requirement (to improve efficiency)

2) Why rewrite equals? In Java's collection framework, equals is used to determine whether two objects are equal.

3) In hibernate, the Set set is often used to store related objects, and the Set set cannot be repeated. Let's talk about the above mentioned in the collection of hashset
When adding an element, how can we determine whether the object is the same? As mentioned above, we only need to rewrite equals.

However, when there are many elements in a hashset, or the rewritten equals () method is complicated, we only use the equals () method for comparison and judgment, and the efficiency will be very low,
So we introduced the hashcode () method to improve efficiency, but I think this is very necessary (so we have to repeat the elements of the hashset with the two principles above)
).

For example, you can write as follows:

Public int hashcode (){

Return 1;} // equivalent to invalid hashcode

The result of this operation is that it cannot be judged when comparing hash codes, because each object returns a hash code of 1, and each time it must be compared to the equals () method before it can be determined.
No, this will of course cause a significant reduction in efficiency.

I have a question. The equals () method is necessary to judge whether the elements are repeated in the hashset as mentioned above (based on the point found online), but it is not involved here.
And the hash table, but this set is called hashset. Why ??

I think the storage operations in hashmap and hashtable still follow the above rules. So I will not talk about it here. These are reading books today, querying materials online, and summarizing them.
Some codes and languages are quoted, but they are indeed summed up by yourself. If you have any errors or are not clear about the details, you can also point out that I am also a beginner, so it is inevitable that there will be errors.
Shared discussion.

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.