Read Catalogue
- An explanation of the Equals () method
- Hashcode () method detailed
- The close relationship between Hashset, Hashmap, Hashtable and Hashcode () and Equals ()
There are two very important methods in the Java.lang.Object class:
12 |
public boolean equals(Object obj) public int hashCode() |
Object
A class is the basis of a class's inheritance structure, so it is the parent class of each class. All objects, including arrays, implement the Object
methods defined in the class.
Back to Top
An explanation of the equals () method
equals()
method is used to determine whether other objects are equal to the object.
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). However, we know that these wrapper classes, such as String, Math, Integer, double, and so on, have overridden the Equals () method of the object class when they use the Equals () method.
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. The classes, such as math, Integer, double, and so on, are all overridden by the Equals () method, thus making a comparison of the content. Of course, the base type is a comparison of the values.
It has the following properties:
-
reflexive (reflexive). For any reference value x that is not null
, x.equals (x)
must be true
.
-
symmetry (symmetric). For any reference value that is not null
x
and y
, when and only if x.equals (y)
is true
, the y.equals (x)
is also true
.
-
transitivity (transitive). For any reference value that is not null
x
, y
, and z
, if x.equals (y)
is true
, while y.equals (z)
is true
, x.equals (z)
must be true
.
-
conformance (consistent). For any reference value that is not null
x
and y
, if the object information used for the equals comparison has not been modified, multiple invocations x.equals (y) The
either returns uniformly true
either returns false
consistently.
-
For any reference value that is not null
x
, x.equals (NULL)
returns false
.
For Object
classes, the equals()
method implements the equivalent of the most differentiated probability on an object, that is, for any non- null
reference value x
and y
, if and only if x
the y
same object is referenced, the method returns true
.
It is important to note that the override is also required when the equals()
method is being override hashCode()
. According to hashCode()
the implementation of the General method, equal objects, their hash code must be equal.
Back to Top
hashcode () method detailed
hashCode()
method returns a hash code value to the object. This method is used for hash tables, such as HashMap.
The nature of this is:
During the execution of a Java application, if the information provided by an object to equals is not modified, the object calls the method multiple times, and hashCode()
the method must consistently return the same integer.
If two objects are equal according to the equals(Object)
method, then calling their respective hashCode()
methods must produce the same integer result.
It does not require equals(java.lang.Object)
two objects that are not equal according to the method, and the respective methods of calling both hashCode()
must produce different integer results. However, programmers should be aware that having different integer results for different objects may improve the performance of hash table.
A number of practices have shown that Object
methods defined by a class hashCode()
return different integers for different objects.
In the object class, Hashcode is defined 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 our own class, such as String, Integer, double, etc. 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 = + * H + val[off++]; } hash = h; } return h; }
Explain this 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 ^ is the exponentiation (the hash code for the empty string is 0).
To understand the role of hashcode, you must first know the collection in Java.
In general, there are two types of collections (Collection) in Java, one is list, and the other is set. The elements within the set are ordered, the elements can be repeated, the latter elements are unordered, but the elements are not repeatable. Here is a question: to ensure that elements are not duplicated, can two elements be repeated according to what to judge?
This is the Object.Equals method. However, if each additional element is checked once, the number of elements that are added to the collection is much more numerous when the element is many. That is, if there are now 1000 elements in the collection, then the 1001th element joins the collection, it calls the Equals method 1000 times. This obviously will significantly reduce efficiency.
Thus, Java uses the principle of a hash table. The hash (hash) is actually a personal name, and because he proposes a hash algorithm, it is named after his name. The hashing algorithm, also known as the hashing algorithm, is to assign the data directly to an address according to a particular algorithm, and the beginner can simply understand that the Hashcode method actually returns the physical address of the object store (which may not actually be).
This way, when the collection is to add a new element, the Hashcode method of the element is called first, and then it can be positioned at the physical location where it should be placed. If there is no element in this position, it can be stored directly in this position without any comparison, and if there is already an element in this position, then the Equals method of calling it is compared with the new element, the same is not saved, and the other address is hashed. So there is a conflict resolution problem here. In this way, the number of actual calls to the Equals method is greatly reduced, almost only one or two times.
In short, hashcode can greatly reduce the number of object comparisons and improve the search efficiency when searching for collections.
The Eqauls methods and Hashcode methods for Java objects are as follows:
1, equal (same) object must have an equal hash code (or hash code).
2. If the hashcode of two objects are the same, they are not necessarily the same.
The following is a description of the equal method and the Hashcode method for the object API:
- If the objects is equal according
equals(Object)
to the method and then calling the method on each of the objects must prod hashCode
UCE the same integer result.
- It isn't required that if, objects was unequal according
equals(java.lang.Object)
to the method and then calling the hashCode
method o n Each of the objects must produce distinct integer results. However, the programmer should is aware that producing distinct integer results for unequal objects may improve the perfor Mance of hash tables.
- The above API description is the official detailed description of the previous 2 points
On the 1th, equal (same) objects must have equal hash codes (or hash codes), why?
Imagine that if two Java objects A and b,a and B are equal (the eqauls result is true), but the hash codes of A and B are different, the HashMap internal Array location index may be different when a and B hash codes are stored in HashMap. Then A and B are likely to allow simultaneous deposit of hashmap, apparently equal/identical elements are not allowed to be stored simultaneously hashmap,hashmap not allow duplicate elements.
On the 2nd, two objects are hashcode the same, they are not necessarily the same
That is, the hashcode of different objects may be the same; If two Java objects A and b,a and B are not equal (the eqauls result is false), but a and B hash codes are equal, a hash conflict occurs when both A and B are stored in the HashMap. That is, A and b are stored in the same position index of the HashMap internal array. At this point HashMap will establish a linked table at that location, and a and B strings will be placed in that position, it is clear that the situation does not violate the HashMap principle of use, is allowed. Of course, the fewer hash collisions, the better, try to use a good hashing algorithm to avoid hash collisions.
So, Java for the Eqauls method and the Hashcode method are defined as:
1. If two objects are the same, their hashcode values must be the same;
2. If the hashcode of two objects are the same, they are not necessarily the same (the objects mentioned here refer to the comparison by the Eqauls method).
If you do not do as required, you will find that the same object can appear in the set set, while the efficiency of adding new elements will be greatly reduced.
3.equals () equal to two objects, hashcode () must be equal, equals () unequal two objects, but does not prove that their hashcode () is not equal.
In other words, the Equals () method is not equal to two objects, and hashcode () is likely to be equal (my understanding is that the hash code generated by the conflict resulted). Conversely, hashcode () must be able to launch equals () and equal to Hashcode (), Equals () may or may not be equal.
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 ( is equal; 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 rewrite code of the string class and also knows Hashcode () The returned results will also be equal. 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.
Back to Top
the close relationship between Hashset, Hashmap, Hashtable and Hashcode () and Equals ()
HashSet is an inherited set interface, and the set interface implements the collection interface, which is a hierarchical relationship. So what is the principle for storing operations in HashSet, Hashmap, and Hashtable to access objects?
The following is an example of hashset, and we all know that duplicate objects are not allowed in the hashset, and that the position of the elements is indeterminate. In the HashSet, how to determine whether the elements are duplicated? In the Java collection, the rule that determines whether two objects are equal is:
1. 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.) )
2. Determine whether two objects are equal with the equals operation
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.
Example 1:
1 package com.bijian.study; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 import java.util.Set; 6 7 public class Hashsettest { 8 9 public static void main (string args[]) {Ten string s1 = new String ("AAA"), one string s2 = new String ("AA A "), System.out.println (S1 = = s2), System.out.println (s1.equals (S2)), System.out.println ( S1.hashcode ()); System.out.println (S2.hashcode ()); Set hashset = new HashSet (); Hashset.add (S1 ), hashset.add (S2), Iterator it = Hashset.iterator (), while (It.hasnext ()) { System.out.println (It.next ()); }23 }24}
Operation Result:
Falsetrue9632196321aaa
This is because the string class has overridden the Equals () method and the Hashcode () method, so HashSet considers them to be equal objects and has been added repeatedly.
Example 2:
1 package com.bijian.study; 2 3 import java.util.HashSet; 4 import java.util.Iterator; 5 6 public class Hashsettest {7 8 public Stati c void Main (string[] args) {9 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 ()); }19 } }21 class Student { num;24 int , string name;25 Student (int num, String name) { This.num = num;28 this.name = name;29 }30 to public String toString () { return num + ":" + name;33 }34}
Operation Result:
1:zhangsan 3:wangwu 2:lisi
Why does hashset add equal elements, and is this a violation of HashSet's principles? 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, and of course the value returned by the Equals () method is not equal.
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 Equals (), so in comparison, it was the Hashcode () method in the inherited object class, and the Hashcode () in the object class The method is a local method, comparing the address of the object (the reference address), using the new method to create the object, two times the generated is of course different objects, resulting in two objects hashcode () the value of the return () is not the same, so HashSet will treat them as different objects.
How to solve this problem? The answer is: Re-hashcode () and the Equals () method in the student class.
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; }}
Operation Result:
1:zhangsan 3:wangwu 2:lisi
You can see that the problem of duplicate elements has been eliminated, according to the overridden method, even if you call the new Student (1, "Zhangsan"), we get the object's hash code, according to the overridden Method Hashcode (), the hash code obtained must be the same, of course, according to equals The () method can also be judged to be the same, so when added to the HashSet collection, it is treated as a repeating element.
Rewrite the Equals () and Hashcode () Summary:
1. The focus is equals, rewriting the hashcode is just a technical requirement (to improve efficiency)
2. Why do you want to rewrite equals? Because in the Java collection framework, the two objects are judged equal by equals.
3. In Hibernate, the set collection is often used to hold related objects, and set collections are not allowed to be duplicated. When you add an element to the HashSet collection, you can actually rewrite the Equals () clause as well. However, when the elements in HashSet are relatively long, or the overridden Equals () method is more complex, we only use the Equals () method to compare and evaluate, the efficiency is very low, so the introduction of the Hashcode () method, only to improve efficiency, and this is very necessary. 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.
Article reference:
Using the Equals () and Hashcode () methods correctly in Java
In Java, the Equals () and hashcode () methods explain in depth the application of the hashcode and hashcode of Java objects in the underlying data structures of HashMap
Answers to some questions about Java hashcode () and Equals ()
From:http://www.cnblogs.com/qian123/p/5703507.html
Java improved article--equals () and Hashcode () method