The equals method and hashCode method of the Object class

The Object class is the parent class of all classes. There are many important methods defined in the Object class. Some basic methods must be clarified. Today we will learn the equals method and the hashCode method in the Object class.

 

1. equals method

First, let's look at the source code of the equals method of the Object class:

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

Obviously it is comparing two object references (i.e. memory addresses) for equality. If you don't know this, take it for granted that it compares content, for example we want to compare two user objects for equality:

User entity class:

public class User {
	
	private int userId;
	private String userName;
	private int age;
	
	public User(int userId, String userName, int age) {
		this.userId = userId;
		this.userName = userName;
		this.age = age;
	}
	
	public int getUserId() {
		return userId;
	}
	public void setUserId(int userId) {
		this.userId = userId;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

Test code: 

public class UserTest {
	
	public static void main(String[] args) {
		User u1 = new User(1, "z3", 25);
		User u2 = new User(1, "z3", 25);
		boolean b = u1.equals(u2);
		System.out.println(b);
	}

}

The execution result is: false, why, because you are calling the equals method of the Object class, which compares the references of two objects, that is, the memory addresses, which are two independent memory spaces on the heap of the Java virtual machine, absolutely Not equal. It's not the result we want, so what should we do? Just override the equals method of the Object class yourself:

We add the equals method to the User entity class:

        @Override
	public boolean equals(Object obj) {
		if (obj == null)
			return false;
		if(obj instanceof User) {
			User other = (User) obj;
			if (age != other.age)
				return false;
			if (userId != other.userId)
				return false;
			if (userName == null) {
				if (other.userName != null)
					return false;
			} else if (!userName.equals(other.userName))
				return false;
		}
		return true;
	}

Execute the test code again, the result is: true

We can see that the overridden equals method compares each member variable of the User class. How to compare the member variables? If it is a basic data type such as int, float, double, boolean, etc., just compare its values ​​directly. .

If it is a string, just call the equals method of the string directly, because the String class rewrites the equals method for us, let's look at its source code:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

 It can be seen that the equals method of the String class compares each char character. In fact, looking at the Jdk source code, you can find that the wrapper classes of various basic data types such as Integer, Float, Double, and Boolean have rewritten the equals method of the Object class. Because the actual business requires us to compare the contents of objects or variables rather than references.

 

2. hashCode method

The source code of the hashCode method of the Object class is as follows:

public native int hashCode();

It is a native method that returns an integer of type int. 

Java provides a hashCode of int type for each object. The purpose is to quickly find and locate the object. Guess, there is a Hash table at the bottom to store the hashCode of the object and the mapping of the memory address, so that the JVM can quickly find and locate in the memory. To a certain object, otherwise, there are so many objects in memory, how does the JVM find an object?

 

hashCode has several important features:

1.hashCode is to find objects or elements to improve performance

2. If the two objects equals equals, then the hashCode of the two objects must be equal

3. If the hashCode of the two objects are equal, the equals of the two objects are not necessarily equal

4. If you want to override the equals method of the object, try to override the hashCode method of the object

 

Next, we explain one by one:

The first point, hashCode is to find objects or elements to improve performance. It has been said above that the JVM needs to find objects in memory and can quickly locate them. There is also the implementation of the collection class, such as the Set collection, the elements are not allowed to be repeated, if there are already 1000 elements in the collection, then when the 1001st element is added to the collection, it will call the equals method 1000 times. This obviously reduces efficiency considerably. So using Java's hash table principle, first locate the element position according to the hashCode of the element, if the element at the position does not exist, insert the element into the position of the collection, if it already exists, compare its content with equals, and if the content is consistent, the element is repeated Otherwise, a chained data structure is used to store it in this location (implementation of HashMap).

 

The second point, if the two objects equals equals, then the hashCode of the two objects must be equal. The Set collection above has already been explained. If the equals of the two objects are equal and the hashCode is not equal, then the two elements will be stored in different locations according to the Set collection implementation, which violates the Set collection elements that are not allowed to be repeated.

 

Point 3, if the hashCodes of two objects are equal, the equals of the two objects are not necessarily equal. Let's take a look at the implementation of Set HashSet, whose bottom layer is the implementation of HashMap:

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key.hashCode());
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
       Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

According to the implementation of the put method of HashMap, we can see that the position of the element in the hash table is first calculated according to the hashCode of the key. If there is already an element in the position (indicating that the hashCode of the two elements are equal), then equals compares the contents of the two elements , if they are not equal, the two elements are stored in this position in a linked list, which fully shows that the two elements hashCode are equal, but equals are not necessarily equal.

 

The fourth point, if you want to rewrite the equals method of the object, try to rewrite the hashCode method of the object. This is actually to ensure the implementation of point 2. If you do not rewrite the hashCode method, or take the Set collection as an example, you cannot guarantee the elements Not repeating. You can view the jdk source code, such as String class, Integer class, etc. as long as the equals method is rewritten, the hashCode method is rewritten.

 

 

To sum up, we develop a good habit during development. Every time we write an entity class, we rewrite its equals method and hashCode method, or we don't write both, and we need to write both, which can reduce unnecessary problems. .

 

 

 

<audio controls="controls" style="display: none;"></audio>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326242499&siteId=291194637