The main content of this article is the correct evaluation method of hashCode in Java, as follows.
There is an optimization for hash lists that can cache the hash code of the object. If the hash code does not match, it will not check the equivalence of the object and directly consider it to be a different object. If the hash code (hashCode) is equal, it will detect whether the objects are equals.
If the objects have the same hash code (hashCode), they are mapped to the same hash bucket. If the hashcode of all objects in the hashlist are the same, the hashlist will degenerate into a linked list, which greatly reduces its query efficiency.
A good hash function usually tends to "generate unequal hash codes for objects that do not want to be waiting for". Ideally, the hash function should evenly distribute instances in the set that do not want to be so on to all possible hashes, but it is very difficult to fully achieve this ideal situation. Here is a relatively simple and effective hashing method:
1. Save a non-zero constant value, such as 17, in a variable of type int called result.
2. For each key domain f in the object ( referring to each domain involved in the equals method ), complete the following steps:
result = 31 * result + c; The multiplication operation is to obtain a better hash function. For example, if the hash function of String omits multiplication, then all strings with different alphabetical order will have the same hash code. The reason why 31 is chosen here is because it is an odd prime number. If the multiplier is an even number and the multiplication overflows, the information will be lost because multiplying with 2 is equivalent to displacement. The benefits of using prime numbers are not obvious, but the hash results are conventionally used to calculate the hash results. 31 has a good feature, that is, using shift and subtraction instead of multiplication, which can achieve better performance: 31 * i == ( i << 5 ) - i. Today's VMs can automatically implement this optimization.If a class is immutable (all domains are final modifications, and all domains are basic types or are immutable classes), and the overhead of calculating hash codes is also relatively high, then you should consider cache the hash code inside the object.
public class HashCodeDemo { static class HashCodeClass { private final boolean bResult; private final final byte byteValue; private final char charValue; private final short shortValue; private final int intValue; private final long longValue; private final float floatValue; private final double doubleValue; private final final String str; private final final int[] arrayValue; //volatile means that the variable is stored and retrieved in memory every time to ensure that the variable is the latest private volatile int hashCode; public HashCodeClass() { bResult = false; byteValue = 1; charValue = 'a'; shortValue = 1; intValue = 1; longValue = 1l; floatValue = 1.0f; doubleValue = 1.0d; str = getClass().getName(); arrayValue = new int[] {1,2,3,4,5}; } @Override public int hashCode() { if(hashCode == 0) { // Set a non-zero initial value to increase the conflict of the zero domain int result = 17; // If the multiplier is omitted, then all strings with different alphabetical order will have the same hash code final int HASH_CODE = 31; result = HASH_CODE * result + (bResult ? 1 : 0); result = HASH_CODE * result + byteValue; result = HASH_CODE * result + charValue; result = HASH_CODE * result + shortValue; result = HASH_CODE * result + intValue; result = HASH_CODE * result + (int) (longValue ^ (longValue >>> 32)); result = HASH_CODE * result + Float.floatToIntBits(floatValue); long doubleLongValue = Double.doubleToLongBits(doubleValue); result = HASH_CODE * result + (int) (doubleLongValue ^ (doubleLongValue >>> 32)); result = HASH_CODE * result + (str == null ? 0 : str.hashCode()); System.out.println("str=" + str + ", str.hashCode=" + str.hashCode()); result = HASH_CODE * result + arrayValue.hashCode(); return result; } return hashCode; } } public static void main(String[] args) { HashCodeClass obj = new HashCodeClass(); System.out.println("obj.hashCode=" + obj.hashCode()); System.out.println("obj="+obj.toString()); }}Output
str=com.demo.test.HashCodeDemo$HashCodeClass, str.hashCode=-205823051obj.hashCode=946611167str=com.demo.test.HashCodeDemo$HashCodeClass, str.hashCode=-205823051obj=com.demo.test.HashCodeDemo$HashCodeClass@386c23df
Summarize
The above is all about this article discussing the correct evaluation method of hashCode in Java, and I hope it will be helpful to everyone. Interested friends can continue to refer to other related topics on this site. If there are any shortcomings, please leave a message to point it out. Thank you friends for your support for this site!