The essential difference and connection between Java learning from cainiao to hashCode () and equals ()

Source: Internet
Author: User

When learning java and using video as an example, you have a deep understanding of the equals and hashcode methods, mainly because they are easy to be confused and prone to errors, I learned from the online materials and shared them with you.

Equals () method


Equals is one of the methods provided by the Object class. As we all know, every java class inherits from the Object class,

Therefore, every object has the equals method. When we use this method, we generally rewrite this method, why?



First look at the source code of the equals () method in an Object class:

 

public boolean equals(Object obj) {     return (this == obj); }

 

From this method, we can see that equals () returns true only when an instance is equal to itself. In general, it compares whether two references point to the same object in the memory, or whether the instances are equal. However, when we use equals () to compare two references to value objects, we often want to know whether they are logically equal, rather than whether they point to the same object-that is why we usually rewrite this method.


Strings1 = new String ("kvill"), String s2 = new String ("kvill"); s1.equals (s2) is ture,


This indicates that the equals () method has been overwritten in the String class. If the equals () method is not overwritten, s1.equals (s2) compares the two objects to the same memory address by default, the return value must be false.


Of course, to rewrite the equals () method, we must abide by the general conventions. From the java. lang. Object specification, the equals method implements the equivalence relationship. The following are the five requirements:


1. Self-inverse: For any reference value x, x. equals (x) must be true.

2. Symmetry: For any referenced values x and y, if x. equals (y) returns true, y. equals (x) returns true.

3. passed: For any reference values x, y, and z, if x. equals (y) returns true, and y. equals (z) also returns true, then x. equals (z) must also return true.

4. consistency: For any reference values x and y, if the object information used for equals comparison is not modified, multiple calls x. equals (y) either returns true consistently or false consistently.

5. non-null: For any non-null reference values x and x. equals (null), false is returned.


HashCode () method


The hashcode () method is also inherited from the object class, which is defined as follows in the object class:

public native int hashCode(); 

HashCode () returns the hash code value of the object, which is usually an integer converted from the internal address of the object. Its implementation is mainly to improve the hash table (such as java. util. hashtable provides the hash table) performance.


Note: in each class that overrides the equals method, you must also override the hashCode method. If you do not do this, it will violate the general conventions of Object. hashCode. As a result, this class cannot work properly with all hash-based collection classes.

The relationship between the return value of hashCode () and equals () is as follows:

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.


Public class TestEquals {public static void main (String args []) {Student s1 = new Student ("Zhang Yi", 6); Student s2 = new Student ("Zhang Yi ", 6); if (s1.equals (s2) {System. out. println ("code with the same s1:" + s1.hashCode () + "s2 Code:" + s2.hashCode ();} else {System. out. println ("not the same") ;}} class Student {private int age; private String name; public Student () {} public Student (String name, int age) {this. age = age; this. name = name;} public int getAge () {return age;} public void setAge (int age) {this. age = age;} public String getName () {return name;} public void setName (String name) {this. name = name;} public int hashCode () {return (this. name. hashCode () + this. age) * 31;} public boolean equals (Object obj) {boolean result = false; if (obj = null) {result = false;} if (this = obj) {result = true;} if (obj instanceof Student) {Student stu = (Student) obj; if (stu. getName (). equals (this. name) & stu. getAge () = (this. age) {result = true ;}} else {result = false ;}return result ;}}

Detailed analysis


Equals () is used to determine whether two sets are equal [the premise is that equals () is overwritten in the class]. = Determines whether the reference value points to the same object.


1. When adding an object to the set, calculate the hashCode code of the object to be added, and obtain a location based on the value to store the current object, if no object exists at this position, the set considers that the object does not exist in the set and adds it directly. If there is an object at this position, compare the objects to be added to the set with the objects at this position using the equals method. If the equals method returns false, if this object does not exist in the Set, a hash is performed again to put the object in the new address calculated after the hash. If the equals method returns true, the Set assumes that the object already exists in the set and will not be added to the set.


2. When rewriting the equals method, you must override the hashCode method. In a java set, 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 to be not equal. If they are equal, they are transferred to 2.

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)

It can be seen that when hashcode () is equal, The equals () method may also be different.



Public static void main (String args []) {String s1 = new String ("zhaoxudong"); // This statement creates two objects, one is the string object "zhaoxudong" (the literal volume stored in the stack), and the other is the object generated in the heap after new. For details, see section 4. 4 String s2 = new String ("zhaoxudong"); // the preceding two statements generate three objects in total, because only one object is generated in the stack. System. out. println (s1 = s2); // falseSystem. out. println (s1.equals (s2); // trueSystem. out. println (s1.hashCode (); // s1.hashcode () equals to s2.hashcode (), pointing to the reference System of the same memory. out. println (s2.hashCode (); // The equals and hashCode methods are only used for comparison between two objects and containers. They have nothing to do with object creation. Set hashset = new HashSet (); hashset. add (s1); hashset. add (s2);/* when s1 and s2 are added, hashset considers s1 and s2 to be equal, so s2 overwrites s1; */Iterator it = hashset. iterator (); while (it. hasNext () {System. out. print Ln (it. next () ;}// at the end of the while LOOP, only a "zhaoxudong" is printed ".



This is because the String class has overwritten the equals () method and hashcode () method.


But look at the following program:

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



Why does hashset add equal elements?


Is this against the hashset principle? A: No, because different hash code values are generated when two newStudent (1, "zhangsan") objects are created based on hashcode, so hashset treats it as a different object. Of course, the values returned by the equals () method also vary. So why does it generate different hash code values? The reason is that the Student class we wrote does not repeat the hashcode () and equals () methods.

Therefore, during the comparison, it is the hashcode () method in the inherited object class. It is a local method that compares the object address (reference address) and creates an object using the new method, the two generated objects are of course different. The result is that the values returned by the hashcode () of the two objects are different. So how can we solve this problem?


The reason is: re-use the hashcode () and equals () methods in the Student class.


Example: class Student {int num; String name; Student (int num, String name) {this. num = num; this. name = name;} public int hashCode () {// override the hashCode method return num * name. hashCode ();} public boolean equals (Object o) {Student s = (Student) o; return num = s. num & name. equals (s. name); // & the Priority Ratio = is low, so no brackets are required before.} public String toString () {return num + ":" + name ;}}

Based on the override method, even if new Student (1, "zhangsan") is called twice, when we obtain the object's hash code, according to the override method hashcode (), the obtained hash code must be the same. Therefore, when running the modified program, we will see that the problem of repeated elements has been eliminated.

Summary

This knowledge is relatively error-prone and must be profound in understanding. Many practices will have a deeper understanding of the principles and definitions. To Do, To Do ......, Wish you a happy New Year!



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.