In practice, it is common to compare two objects for equality, such as the address class below, which has two properties: String Province and String city.
Public classAddress {PrivateString Province; PrivateString City; PublicString getprovince () {returnProvince; } Public voidsetprovince (String province) { This. Province =Province; } PublicString getcity () {returnCity ; } Public voidsetcity (String city) { This. City =City ; } PublicAddress () {} PublicAddress (String Province, String city) { This. province = Province; This. City =City ;} }
In real life we think that if the province and city properties of the two address are the same , they should be the same address (provinces and cities alike, of course, the same region). But the following code shows that: Address1 and Address2 are two "different addresses"
1 Public classtestaddress {2 3 Public Static voidMain (string[] args) {4Address Address1 =NewAddress ("Guangdong", "Guangzhou");5Address Address2 =NewAddress ("Guangdong", "Guangzhou");6 7System.out.println (Address1 = = Address2);//false8System.out.println (Address1.equals (address2));//false9System.out.println (address1.hashcode () = = Address2.hashcode ());//falseTen } One}
The reason for this is that comparing objects in Java (programming language) with real-life comparison of two objects is two different concepts, the former is called "Physical equality", and the latter is "logical equality".
Adress1==adress2 is based on whether the memory address of two objects is the same, the 4th, 5 rows are new two objects, the two objects stored in the memory of different addresses, of course, not equal.
Because the address class does not override the Equals method, Address1.equals (ADDRESS2) executes the Equals method of the object class, and the Equlas method of the Java.lang.Object class is implemented like this:
Public Boolean equals (Object obj) { return (this= = obj); }
The method is commented on in the JDK as follows: That is, the Equals method of the object class is to compare two objects by = = To determine whether the object X and object y are equal, depending on whether the object x reference and the reference to object Y point to the same address in memory.
* The {@code equals} method for class {@code Object} implements * The most discriminating possible equivalence relatio N on objects; Non-null reference values {@code x} and this method returns {@code true} if and only * if { @code x} and {@code y} refer to the same object * ({@code x = = y} has the value {@code true}).
And according to the realistic thinking, since Adress1 and address2 all represent Guangdong and Guangzhou, then their two objects in the program should be equal (logically equal), that is, address1.equals (ADDRESS2) should return true. Then you need to overwrite the Equals method and the Hashcode method in the Object class.
It is tricky to override the Equals method and the Hashcode method.
① overrides the Equals method of the object class, you need to overwrite the Hashcode method of the object class. Why is it? ----Do not violate the "Hashcode Convention (general contract)"
The comments on the Equals method of the object class are as follows:
/* Note that it was generally necessary to override the {@code hashcode} thismaintain the
* General contract for the {@code Hashcode} method, which states * that equal Objects must have equal hash codes. * /Publicboolean equals (Object obj) {return (This = = obj); }
And this "General Convention" is:? If two objects compare equality according to the Equals (object) method, the Hashcode method that calls either object in both objects must produce the same integer result.
? If two objects are not equal according to the Equals (object) method, the Hashcode method that calls either object in the two objects can produce the same integer result , but it is better to produce a different integer result, which provides the performance of the hash table (if you want to put the address class as a key into HashMap, you can reduce the conflict, refer to this article)
And how exactly does it cover equals ()? "Effective JAVA" gives the method, the routine is the same, its goal is to ensure: reflexivity, symmetry, consistency. In summary, for the address class above, this can be:
1 @Override2 Public Booleanequals (Object obj) {3 if(obj = = This)4 return true;5 if(! (objinstanceofAddress))6 return false;7Address address =(Address) obj;8 return address.getprovince (). Equals (province) && address.getcity (). Equals (city);9}
Line 8th shows that if the two address province and City are the same, then the two address is the same, so that the Equals method returns True. (Does not consider the case of strings)
After the Equals () is covered, the next step is to overwrite hashcode (). The target of covering hashcode () is:
If two objects address1.equals (ADDRESS2) return false, then Address1.hashcode () is best not equal to Address2.hashcode ()
Of course, there is no super-perfect Hashcode (), if equal, then Hashmap.put (address1,value1) hashmap.put (address2,value2) will be put into the same hashMap of the same slot.
The address classes for the overridden equals and Hashcode are as follows:
Public classAddress {PrivateString Province; PrivateString City; PublicString getprovince () {returnProvince; } Public voidsetprovince (String province) { This. Province =Province; } PublicString getcity () {returnCity ; } Public voidsetcity (String city) { This. City =City ; } PublicAddress () {} PublicAddress (String Province, String city) { This. province = Province; This. City =City ;} @Override Public Booleanequals (Object obj) {if(obj = = This) return true; if(! (objinstanceofAddress)) return false; Address Address=(Address) obj; returnAddress.getprovince (). Equals (province) &&address.getcity (). Equals (city); } @Override Public inthashcode () {intresult = 17; Result+ = 31 *Province.hashcode (); Result+ = 31 *City.hashcode (); returnresult; }}
The test classes are as follows:
ImportJava.util.HashMap;ImportJava.util.Map; Public classtestaddress { Public Static voidMain (string[] args) {Address Address1=NewAddress ("Guangdong", "Guangzhou"); Address Address2=NewAddress ("Guangdong", "Guangzhou"); System.out.println (Address1= = Address2);//falseSystem.out.println (Address1.equals (address2));//trueSystem.out.println (address1.hashcode () = = Address2.hashcode ());//trueAddress diff1=NewAddress ("Sichuan", "Chengdu"); Address diff2=NewAddress ("Sichuan", "Mianyang"); System.out.println (diff1= = diff2);//falseSystem.out.println (Diff1.equals (diff2));//falseSystem.out.println (diff1.hashcode () = = Diff2.hashcode ());//falseMap<address, integer> HashMap =NewHashmap<address, integer>(); Hashmap.put (Address1,1); Hashmap.put (Address2,2);//the Address2 hashcode and Address1 are the same, so the Put method overrides the Address1 corresponding value of value 1System.out.println (Hashmap.get (Address1));//2System.out.println (Hashmap.get (address2));//2hashmap.put (diff1,1); Hashmap.put (DIFF2,2); System.out.println (Hashmap.get (diff1));//1System.out.println (Hashmap.get (diff2));//2 }}
Finally, in fact, Eclipse provides us with the method of automatically generating equals and hashcode, which can be referenced by the Equals method in Java and the Hashcode method. The auto-generated method is as follows: (or auto-generated more professional ....) )
@Override Public inthashcode () {Final intPrime = 31; intresult = 1; Result= Prime * result + (city = =NULL) ? 0: City.hashcode ()); Result= Prime * result + ((province = =NULL) ? 0: Province.hashcode ()); returnresult; } @Override Public Booleanequals (Object obj) {if( This==obj)return true; if(obj = =NULL) return false; if(GetClass ()! =Obj.getclass ())return false; Address Other=(Address) obj; if(City = =NULL) { if(Other.city! =NULL) return false; } Else if(!city.equals (other.city))return false; if(Province = =NULL) { if(Other.province! =NULL) return false; } Else if(!province.equals (other.province))return false; return true; }
Reference: "Effective Java"
Http://www.cnblogs.com/hapjin/p/4582795.html
Original: http://www.cnblogs.com/hapjin/p/7327839.html
Java correctly customizes the comparison object---How to override the Equals method and the Hashcode method