A detailed explanation of hashcode () and Equals () in Java

Source: Internet
Author: User

This afternoon to study the half-day hashcode () and Equals () method, finally have a little bit of understanding, write down to share with you (Zhaoxudong 2008.10.23 late 21.36).
1. Both 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 clear that the address values of two objects are compared (that is, if the comparison reference is the same). But we need to know that when string, Math, and Integer, Double .... When these encapsulation classes use the Equals () method, the Equals () method of the object class has been overridden. For example, in the String class, the following:
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 a comparison of what is being done, and it is no longer an address comparison. Double, Integer, Math ... in turn. Wait, these classes are all overriding the Equals () method, thus making a comparison of the content. Of course, the basic type is the comparison of values, this is nothing to say.
We should also note that the Java language requirements for Equals () are as follows, and these requirements must be followed:
• Symmetry: If X.equals (y) returns "true", then Y.equals (x) should also return "true".
• Reflectivity: X.equals (x) must return "true".
• Analogies: 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 X and Y contents remain constant, the return is "true" no matter how many times you repeat X.equals (y).
• In any case, x.equals (NULL) will always return "false", and X.equals (and X objects of different types) will always return "false".
These five points are the criteria that must be adhered to when overriding the Equals () method, and if the violation will result in unexpected results, please be sure to follow.
2. Next is the Hashcode () method, which is defined in the object class as follows:
public native int hashcode ();
The description is a local method, and its implementation is dependent on the local machine. Of course we can overwrite the Hashcode () method in the class we write, such as String, Integer, Double .... Wait, these classes are all covered by the hashcode () method. 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 the program (written in the string's API):
s[0]*31^ (n-1) + s[1]*31^ (n-2) + ... + s[n-1]
Using the int algorithm, where s[i] is the I-character of a string, n is the length of the string, and ^ denotes exponentiation. (The hash code for an empty string is 0.) )

3. Here we first need to understand a question:
Equals () equal to two objects, hashcode () must be equal;
Equals () is not equal to two objects, but does not prove that their hashcode () are unequal. In other words, the Equals () method is not equal to two objects, and hashcode () may be equal. (My understanding is that the hash code was generated when the conflict was created).
Conversely: hashcode () can not be equal to the introduction of equals (), and hashcode () is equivalent, Equals () may be equal or unequal. To explain the scope of use of the 3rd, my understanding is that it can be used in classes such as Object, string, and so on. In the object class, the Hashcode () method is the local method that returns the address value of the object, and the Equals () method in the object class compares the address values of the two objects, and if Equals () is equal, the two object address values are equal, of course hashcode ( In the String class, Equals () returns a comparison of two object contents, and when two object contents are equal,
The Hashcode () method is based on the parsing of the string class (which is already parsed in the 2nd), and it is also known that hashcode () will return the same result. And so on, you can know that the overridden equals () and Hashcode () methods in a wrapper class such as Integer and double are also appropriate for this principle. Of course, there are no overridden classes that follow this principle after inheriting the Equals () and Hashcode () methods of the object class.

4. When it comes to hashcode () and Equals (), it is impossible to mention the use of hashset,hashmap,hashtable in the following analysis:
HashSet is an inherited set interface, and the set interface implements the collection interface, which is a hierarchical relationship. So what is the principle of hashset to access objects?
Duplicate objects are not allowed in hashset, and the position of the elements is indeterminate. In the HashSet, how to determine whether the elements are duplicated? This is the crux of the problem, after an afternoon of query verification finally got a little revelation, and share with you, in the Java collection, the rule to determine whether two objects are equal:
1) to determine whether the hashcode of two objects are equal
If it is not equal, the two objects are not equal, complete
If equal, transfer to 2)
(This is only to improve the storage efficiency requirements, in fact, it is not possible, but if not, the actual use of efficiency will be greatly reduced, so we will do it as necessary.) The question will be highlighted later. )
2), determine whether two objects are equal by equals
If not equal, neither object is considered equal
If equal, two objects are considered equal (equals () is the key to determine whether two objects are equal)
Why is the two rule not to use the first one? No, because as already said, the Equals () method may also be unequal when hashcode () is equal, so it is necessary to use the 2nd rule to limit the inclusion of non-repeating elements.
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,s2, using the two-point guideline mentioned above, you can know that hashset think S1 and S2 are equal, adding duplicate elements, so S2 is covered s1;*/
Iterator It=hashset.iterator ();
while (It.hasnext ())
{
System.out.println (It.next ());
}
Finally, in the while loop, only one "Zhaoxudong" is printed out.
The output is: false
True
-967303459
-967303459
This is because the string class has overridden the Equals () method and the Hashcode () method, so when judged according to rule 1.2 above, HashSet considers them to be equal objects and has been 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;
}
}
The output is:
1:zhangsan
1:zhangsan
3:wangwu
2:lisi
The question arises, why did hashset add equal elements, is it not the same as the hashset principle? The answer is: no
Because a different hash code value is generated when compared to a new Student (1, "Zhangsan") object that was established based on Hashcode () two times, HashSet treats him as a different object, of course, equals () The value returned by the method is not equal (this does not have to be explained). So why would a different hash code value be generated? Do we not generate the same hash code when comparing S1 and S2? The reason is that the student class we wrote ourselves did not re-hashcode () and the Equals () method, so in comparison, it is the Hashcode () method in the inherited object class, hehe, you remember the hashcode () in the object class What is the comparison of the method?!
It is a local method, compared to the address of the object (the reference address), using the new method to create the object, two times generated is of course different objects (this everyone can understand it ...) ), the result is that the value returned by the hashcode () of two objects is not the same. Therefore, according to the first criterion, HashSet will treat them as different objects, and naturally they do not need to be judged by a second criterion. So how to solve this problem??
The answer is: Re-hashcode () and the Equals () method 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;
}
}
According to the overridden method, even if you call new Student (1, "Zhangsan") two times, we obtain the hash code of the object, according to the overridden Method Hashcode (), the hashes obtained will certainly be the same (this should be no doubt about it).
Of course, according to the Equals () method we can also judge the same. So when adding to the HashSet collection, treat them as repeating elements. So when we run the modified program, we find that the result is:
1:zhangsan
3:wangwu
2:lisi
You can see that the problem of repeating elements has been eliminated.
About the problem of re-equals () and Hashcode () in Hibernate's Pojo class:
1), the focus is equals, rewrite hashcode just technical requirements (in order to improve efficiency)
2), why do you rewrite equals, because in the Java collection frame, you are using equals to determine whether two objects are equal
3), in Hibernate, the set collection is often used to hold related objects, and set collections are not allowed to be duplicated. Let's talk about the criteria for how to tell if an object is the same when adding elements to the HashSet collection, which says two, as long as you rewrite the Equals () clause.
However, when the elements in the hashset are relatively long, or the overridden Equals () method is more complex, we only use the Equals () method to compare the judgement, the efficiency is very low, so introduced the hashcode () This method, just to improve efficiency, But I think this is very necessary (so we hashset the elements in the previous two rules to determine whether the element is repeated).
For example, it can be written like this:
public int hashcode () {
return 1;} Equivalent to hashcode invalid
The effect of this is to compare the hash code can not be judged, because each object returns a hash code is 1, each time must be compared to the Equals () method to determine whether or not to repeat, which of course will cause a significant reduction in efficiency.
I have a question, if it is the Equals () method (according to the view found on the Internet) that is necessary to judge whether an element is duplicated in HashSet, as mentioned earlier, but there is no question about a hash table, but this set is called HashSet, why??
I think the storage operation in Hashmap,hashtable still adheres to the above guidelines. So there's no more talking here. These are reading today, online query information, summed up their own, part of the code and language is quoted, but it is true that they summed up. There are mistakes and not the details of the place also please point out that I am also a beginner, so there will inevitably be the wrong place, I hope we can discuss together.

Transferred from: http://www.iteye.com/topic/257191

A detailed explanation of hashcode () and Equals () in Java

Related Article

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.