Equals common interview questions
Before starting the chat, let's look at a few common interview questions and see if you can answer them all.
- 1. What is the difference between equals and ==?
- 2. Are two objects with equal hashcodes == equal? Is equals equal?
- 3. If two objects are compared with equals to be equal, are their hashcodes equal?
If we do not rewrite equals and hashcode, then it uses the implementation of the Object method. Let's take a brief look
public boolean equals(Object obj) {
return (this == obj);
}
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
Why rewrite equals
It can be seen from the above code that when the equals provided by Object is compared, it is not a value comparison, but a memory address comparison. From this we can know that if you want to use equals to compare objects, you must rewrite equals.
What are the problems when rewriting equals without rewriting hashCode
Let's look at the following paragraph first
In every class that covers the equals method, hashCode must be covered. If you don't do this, it violates the general convention of hashCode, which is what is said in the comment above. As a result, this class cannot be combined, so it works normally with the hash collection, which refers to HashMap, HashSet, HashTable, and ConcurrentHashMap.
from Effective Java 3rd Edition
Conclusion: rewrites equals without rewriting hashCode, it will not work with the hash set.
In this case, let's take the HashMap we are most familiar with for demonstration and derivation. We know that the keys in the HashMap cannot be repeated. If you add them repeatedly, the ones added later will overwrite the previous content. Then let's take a look at how HashMap determines the uniqueness of the key.
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Looking at the code, it is found that it determines the storage location in the linked list by calculating the hashCode value of the Map key. Then it can be inferred that if we rewrite equals but not hashCode, there may be a contradiction in element duplication.
Let's demonstrate
public class Employee {
private String name;
private Integer age;
public Employee(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Employee employee = (Employee) o;
return Objects.equals(name, employee.name) &&
Objects.equals(age, employee.age);
}
/*@Override
public int hashCode() {
return Objects.hash(name, age);
}*/
}
public static void main(String[] args) {
Employee employee1 = new Employee("冰峰", 20);
Employee employee2 = new Employee("冰峰", 22);
Employee employee3 = new Employee("冰峰", 20);
HashMap<Employee, Object> map = new HashMap<>();
map.put(employee1, "1");
map.put(employee2, "1");
map.put(employee3, "1");
System.out.println("equals:" + employee1.equals(employee3));
System.out.println("hashCode:" + (employee1.hashCode() == employee3.hashCode()));
System.out.println(JSONObject.toJSONString(map));
}
According to the normal situation, there are only two elements in the map, employee2 and employee3.
execution result
The reason for this problem is that the hashCode is not rewritten. When the map calculates the hash value of the key, objects with the same absolute value are calculated except for inconsistent hash values.
Next we open the annotation code of hashCode to see the execution result
Summarize
If equals is rewritten, hashCode must be rewritten. If it is not rewritten, it will cause conflicts with hash sets (HashMap, HashSet, HashTable, ConcurrentHashMap).
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。