preface

As a programmer who has been dealing with CRUD and HTML writing for a long time, I also wanted to improve myself, so I chose to have a deep understanding of Java and start by imitating some mainstream frameworks. This time, WE choose hashCode. As a basic method of object, hashCode plays a crucial role in the data structure of hash tables and hash algorithms, such as hashMap and hashSet.

What is the hashCode

This method returns the hash value of the Object, in order to support hash tables such as HashMap. Here’s what hash is:

www.cnblogs.com/jiewei915/a…

www.cnblogs.com/dolphin0520…

Quote the articles of two bloggers on the Internet as an understanding of hash.

Here’s a brief introduction to hashCode:

Is it possible to determine whether two objects are equal based directly on the hashcode value? Definitely not, because different objects might generate the same HashCode value. Although two objects cannot be judged to be equal based on the hashcode value, they can be judged to be unequal based on the hashcode value. If the hashcodes of two objects are unequal, they must be two different objects. If you want to determine whether two objects are truly equal, you must use the equals method. That is, for two objects, if the equals method is true, the hashcode values of the two objects must be equal. If equals returns false, the hashcode values of the two objects need not be different; If two objects have different hashCode values, equals must return false; If the hashcode values of two objects are equal, the result of equals method is unknown.

If two objects have the same hashcode value, the equals method will get unknown results. The above argument is taken from a blogger on the Internet. Based on this, we are worried that the same situation might occur with hashCode.

Why rewrite hashCode

Most of the rewriting of hashCode happens when you override Equals (in my humble opinion). The source code for hashCode in Object says:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
  • Machine dafa translation:
  • Whenever it is called on the same object multiple times during the execution of the Java application, the hashCode method must always return the same integer, provided that the information used in the Equals comparison on the object is not modified. The integer does not need to be consistent from one execution of the application to another execution of the same application.
  • If two objects are equal according to the equals (Object) method, calling the hashCode method on each of the two objects must produce the same integer result.
  • If two objects are not equal according to the equals (java.lang.object) method, it is not necessary to call the hashCode method on each of the two objects to produce different integer results. However, programmers should be aware that generating different integer results for unequal objects may improve hash table performance.

To override equals, hashCode must also fetch the same value.

public class People {
    private String name;
    private int age;

    public People(String name,int age) {
        this.name = name;
        this.age = age;
    }

    public void setAge(int age){
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        return this.name.equals(((People)obj).name) && this.age== ((People)obj).age;
    }

    public static void main(String[] args) {

        People p1 = new People("Jack".12);
        System.out.println(p1.hashCode());
        People p2 = new People("Jack".12);
        System.out.println(p2.hashCode());

        HashMap<People, Integer> hashMap = new HashMap<People, Integer>();
        hashMap.put(p1, 1); System.out.println(hashMap.get(p2)); }}Copy the code

Obviously, the two created People are different hashcodes, but using my rewrite of equals results in the same result.

Add a P1 object to the HashMap and use the get(p2) method to find it using p2. If hashCode is not overridden, null is returned (but against the intent of this code, the same object returns the same value).

Get method in HashMap

public V get(Object key) {
    Node<K,V> e;
    return (e = getNode(hash(key), key)) == null ? null : e.value;
}

static final int hash(Object key) {
    int h;
    return (key == null)?0 : (h = key.hashCode()) ^ (h >>> 16);
}
Copy the code

The hashCode method is used to get the corresponding value; We can solve this problem if we rewrite the corresponding hashCode.

@Override
public int hashCode(a) {
    return name.hashCode()*31+age;
}
Copy the code

So the same objects in our equals logic will return the same hashCode, which will fetch the value in the hashMap.

Overrides hashCode common in the JDK

The example here, the most important example, is the String rewrite of hashCode.

public int hashCode(a) {
    int h = hash;
    if (h == 0 && value.length > 0) {
        char val[] = value;
        for (int i = 0; i < value.length; i++) {
            h = 31 * h + val[i];
        }
        hash = h;
    }
    return h;
}
Copy the code

Why does a common rewrite of hashCode use 31

This is a mathematical discussion category that I won’t go into here. I’ll just quote blog.csdn.net/qq_38182963… One of the conclusions:

“As you can see, the main reason for using 31 is performance. You could use 63. But 63 is a bigger spillover risk. How about 15? Think about it.”