preface
Previous article how to use Spring data binding well? The soul questioning session left a question about equals and Hashcode. Basic interview often run into the related problems, this is not a complicated problem, but a lot of friends suffer from that they two relations and constraints, so write this article for that alone, this article will gradually (through, for example, Let the memory and understanding more easily) illustrate these Let you worry some problems, Let ‘s go…
Interview questions
1. Why do we need equals when we have the == operator in Java?
Equals compares object addresses and equals compares object values
Let’s take a look at equals in the Object class:
public boolean equals(Object obj) {
return (this == obj);
}
Copy the code
We see that equals also compares object addresses by ==, without helping us compare values. Object is definitely an “ancestor” in the Java world, and the == sign cannot be changed or overwritten. But equals is a method, which gives us the possibility to override equals to compare values:
@Override
public boolean equals(Object obj) {
// Rewrite the logic
}
Copy the code
When you buy a new computer, each computer has a unique serial number. Normally, two identical computers are put in front of you. Would you say that because the serial number is different, these two computers are different?
If we say that two computers are the same, we usually compare their “make/size/configuration”, as in:
@Override
public boolean equals(Object obj) {
returnBrand equal & size equal & configuration equal}Copy the code
When we encounter the above scenario, we need to override the equals method. This explains why the Java world has == and equals problems.
2. equals
Equal andhashcode
Equal to the problem
There are two questions you often come across about both:
- Two objects
equals
Equal, then theyhashCode
Equal? - Two objects
hashCode
Equal, then theyequals
Equal?
To illustrate the two conclusions, here’s an unfortunate example, just for memorization purposes, equals is compared to the spelling of a word; HashCode is like the sound of a word, in the same context:
They also pronounce /si/curliest, so hashCode is equal, which answers the first question:
Two objects
equals
Equal, then theyhashCode
Must be equalThe answer to the second question is,
Two objects
hashCode
Equal, then theyequals
Not necessarily equal
Look at the Object class hashCode method:
public native int hashCode(a);
Copy the code
Go ahead and look at the comments for the method, explicitly stating the constraints on the method
There is also a constraint on overriding equals behind this result
3. Rewrite theequals
What are the constraints?
The constraint on overriding equals is also clearly stated in the comment for the equals method, which I’ll repeat here:
Red orange red green green blue purple, colorful Israel; Do re mi fa la, do re la la, do re mi fa la la, do re mi fa La La, do re mi Fa La La, do re mi Fa La la, do re mi Fa La la, do re mi Fa La la, do re mi Fa La la, do re mi Fa La La, do re mi Fa La La
4. When do we need to rewritehashCode
?
To compare values, we override equals, but when do we override hashCode?
Usually whenever we override equals we override hashCode
Why is there such a constraint? If two objects are equal to equals, their hashCode must also be equal. Let’s see what happens if we just override equals and not hashCode. Here’s an example:
Define the student class and use the IDE to just generate equals for us:
public class Student {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null|| getClass() ! = o.getClass())return false;
Student student = (Student) o;
returnage == student.age && Objects.equals(name, student.name); }}Copy the code
Write test code:
Student student1 = new Student();
student1.setName("A soldier of the Sun arch");
student1.setAge(18);
Student student2 = new Student();
student2.setName("A soldier of the Sun arch");
student2.setAge(18);
System.out.println("Student1. Equals (student2) equals: + student1.equals(student2));
Set<Student> students = new HashSet<Student>();
students.add(student1);
students.add(student2);
System.out.println("Student Set length is:" + students.size());
Map<Student, java.lang.String> map = new HashMap<Student, java.lang.String>();
map.put(student1, "student1");
map.put(student2, "student2");
System.out.println(Student Map set length is: + map.keySet().size());
Copy the code
View the run result:
Student1. equals(student2) equals: true Student Set length: 2 Student Map length: 2Copy the code
Student1 and student2 are obviously two objects by Set and Map, because when you call their PUT (Set add, HashMap put), you check whether the hash value is equal. Open the JDK and check it out for yourself
So we continue to rewrite the Student class hashCode method:
@Override
public int hashCode(a) {
return Objects.hash(name, age);
}
Copy the code
Rerun the above test to see the results:
Student1. equals(student2) equals: true Student Set length: 1 Student Map length: 1Copy the code
We get what we expect, which is why we usually override equals and why it’s best to override hashCode as well, okay
-
If you’re using Lombok, have you noticed that Lombok has only one @equalSandHashCode annotation instead of splitting it into @equals and @hashCode annotations? For more on Lombok, Also check out my previous article on the use of Lomok
-
In addition, when overriding methods are generated using IDE shortcuts, you will also see the two methods together instead of being separated like getters and setters
The above two points are invisible standard constraints, we hope that we also strictly abide by this standard, in order to prevent unnecessary trouble, there are various ways to remember, if you can not remember this word constraints, remember the above picture in your mind you will understand
5. Rewrite thehashCode
Why is there always the number 31?
If you are careful, you may have noticed that the way I overwrote hashCode above is very simple, using the objects.hash method.
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
Copy the code
Here 31 is used to compute the hash value of the object
How to make good use of Spring data binding? At the end of the article mentioned in HandlerMethodArgumentResolverComposite class has a member variable like this:
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>(256);
Copy the code
The Map’s key is MethodParameter. This class must override the equals and hashCode methods as well
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if(! (otherinstanceof MethodParameter)) {
return false;
}
MethodParameter otherParam = (MethodParameter) other;
return (this.parameterIndex == otherParam.parameterIndex && getMember().equals(otherParam.getMember()));
}
@Override
public int hashCode(a) {
return (getMember().hashCode() * 31 + this.parameterIndex);
}
Copy the code
Why is the number 31 used to compute the hash value? Why does the String hashCode method select the number 31 as the multiplier
conclusion
If you’re still confused about equals and hashCode relationships and constraints, just follow the steps above to recall them, or better yet, look directly at the JDK source; In addition, it is a very good way to take out actual examples to verify. If you still have relevant question, can also leave a message to discuss.
Soul asking
- The Thread class is not overwritten
equals
Method, you know what else you don’t need to rewriteequals
Methods? - From above HandlerMethodArgumentResolverComposite class member variables defined in the Map, you notice what knowledge, such as final, ConcurrentHashMap, capacity person, why do you want to write? Can you explain why?
Welcome to continue to pay attention to the public account: “One soldier of The Japanese Arch”
- Cutting-edge Java technology dry goods sharing
- Efficient tool summary | back “tool”
- Interview question analysis and solution
- Technical data to receive reply | “data”
To read detective novel thinking easy fun learning Java technology stack related knowledge, in line with the simplification of complex problems, abstract problems concrete and graphical principles of gradual decomposition of technical problems, technology continues to update, please continue to pay attention to……