reference resources: segmentfault.com/a/119000001864789...
Today, a friend suddenly asked a question:
When two objects use x.equals(y) to judge that the result is true, can the hashcodes of the two objects be different?
In Java programming, equals() or = =) is often used to judge whether two objects are equal, but the difference and principle may not be completely clear to many people. Today, let's take a look at the difference and principle between equals() and = =.
1. Meaning of data type and = =
Data types in Java are divided into basic data types and reference data types:
Basic type: the smallest granularity data type built into the programming language. It includes four categories and eight types
- Four integer types: byte, short, int, long
- There are two types of floating point numbers: float and double
- 1 character type: char
- 1 boolean type: Boolean
Reference type: reference is also called handle. Reference type is a data form defined in the programming language that stores the address value of the address where the actual content is located in the handle
- class
- Interface
- array
- For basic types, = = compares their values
- For reference types, = = compares their addresses in memory (heap memory addresses)
Example:
public void test(){ int num1 = 100; int num2 = 100; String str1 = "James"; String str2 = "James"; String str3 = new String("James"); String str4 = new String("James"); System.out.println("num1 == num2 : " + (num1 == num2)); System.out.println("str1 address : " + System.identityHashCode(str1) + ";\nstr2 address : " + System.identityHashCode(str1) + ";\nstr1 == str2 : " + (str1 == str2)); System.out.println("str3 address : " + System.identityHashCode(str3) + ";\nstr4 address : " + System.identityHashCode(str4) + ";\nstr3 == str4 : " + (str3 == str4)); }
Run the above code to get the following results:
num1 == num2 : true str1 address : 1174290147; str2 address : 1174290147; str1 == str2 : true str3 address : 1289696681; str4 address : 1285044316; str3 == str4 : false
You can see that the memory addresses of str1 and str2 are 1174290147, so = = is used to judge as true, but the addresses of str3 and str4 are different, so it is judged as false.
2. Analysis of equals() method
In the Java language, all classes inherit from the superclass Object. There is also an equals() method in this class. Let's take a look at this method first.
public boolean equals(Object obj) { return (this == obj); }
It can be seen that this method is very simple, which is to compare the memory address of the object. Therefore, when the object does not override this method, this method is used by default, that is, compare the memory address value of the object. However, classes such as String and Integer have overridden equals(). Let's take String as an example.
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = length(); if (n == anotherString.length()) { int i = 0; while (n-- != 0) { if (charAt(i) != anotherString.charAt(i)) return false; i++; } return true; } } return false; }
Obviously, the equals() method of String just compares its data value, not the memory address of the object.
Take String as an example to test.
public void test() { String str1 = "James"; String str2 = "James"; String str3 = new String("James"); String str4 = new String("James"); System.out.println("str1 address : " + System.identityHashCode(str1) + ";\nstr2 address : " + System.identityHashCode(str1) + ";\nstr1.equals(str2) : " + str1.equals(str2)); System.out.println("str3 address : " + System.identityHashCode(str3) + ";\nstr4 address : " + System.identityHashCode(str4) + ";\nstr3.equals(str4) : " + str3.equals(str4)); }
The result is:
str1 address : 1174290147; str2 address : 1174290147; str1.equals(str2) : true str3 address : 1289696681; str4 address : 1285044316; str3.equals(str4) : true
It can be found that whether the memory address of the object is the same or not does not affect the result, so the String type compares the data value rather than the memory address value.
So summarize the difference between equals() and = =:
Basic types: compare whether their values are equal Reference type: compare whether their memory addresses are equal equals() Basic type: use==Compare Reference type: by default, compare whether their addresses are equal; If equals()If the method is overridden, it is compared according to the rewriting requirements.
equals() and hashCode()
After understanding the roles and differences between = = and equals() in detail, let's study the previous problem:
When two objects use x.equals(y) to judge that the result is true, can the hashcodes of the two objects be different?
First, we need to know what hashCode is? Let's take a look at the superclass Object.public int hashCode() { return identityHashCode(this); // The memory address value of the object is returned here }
The code is also very simple. It seems that by default, hashCode is equal to the memory address value of the object (Note: the System.identityHashCode(Object obj) method is used to obtain the memory address of the object, which was used in the previous sample code). Like the equals() method, after rewriting, the hashCode() method can also be rewritten, and the two generally appear in pairs.
Simply test what happens when a String type overrides the hashCode() method.public void test() { String str1 = "James"; System.out.println("str1 address : " + System.identityHashCode(str1) + "\nstr1 hashCode : " + str1.hashCode()); }
summary
So far, the difference and function between = = and equals(), the relationship and use of equals() and hashCode have been understood. Here's a summary:For the difference between equals() and = =:
Basic types: compare whether their values are equal Reference type: compare whether their memory addresses are equal
equals()
Basic type: use==Compare Reference type: by default, compare whether their addresses are equal; If equals()If the method is overridden, it is compared according to the rewriting requirements
For the relationship between equals() and hashCode():
According to the documentation in the Object superclass, the equals() and hashCode() methods should be both forward and backward. The above example only illustrates that situation, but it is not a good application.So remember that the equals() and hashCode() methods should go forward and backward together.
So remember that the equals() and hashCode() methods should go forward and backward together.
So remember that the equals() and hashCode() methods should go forward and backward together.