我有一个Employee
课,我覆盖了hashCode()
方法,而不是equals()
方法
public class Employee {
public int id;
public String name;
public Employee (int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
现在,客户端会添加3个hashCode()
将相同的数据。
public class EmployeeTest {
public static void main(String...args) {
Employee emp1 = new Employee(11, "Arunan");
Employee emp2 = new Employee(22, "Arunan");
Employee emp3 = new Employee(33, "Arunan");
HashMap<Employee,Employee> map = new HashMap<>();
map.put(emp1, emp1);
map.put(emp2, emp2);
map.put(emp3, emp3);
Employee emp = map.get(emp3);
System.out.println(emp.id);
}
}
现在根据我的理解,上面3个对象最终会在hashmap中的同一个桶中。由于未实现equals()
,因此HashMap很难识别特定对象。但是在上面的程序中,我得到了emp3对象,它正确地获取了emp3对象。 hashmap如何工作?
答案 0 :(得分:3)
你是对的,他们最终会在同一个桶里。
如果没有重写equals
方法,JVM只会比较对象引用是否相等。
在你的情况下,当你放入地图时,你将同一个对象传递给map.get()
,因此引用将是相等的,因此它与对象匹配。
尝试创建:
Employee emp3CantFindMe = new Employee(33, "Arunan")
你会发现尝试从地图中检索它会导致null,即使它看起来与emp3
“相同”。
答案 1 :(得分:0)
如果两个对象实际上是同一个对象,则equals()
的默认实现返回true。在您的情况下,您使用放入hashmap的相同对象(emp3
)来查询hashmap。这就是它运作的原因。
答案 2 :(得分:0)
HashMap首先使用hashCode
查找可能的候选项,然后使用equals
查找您要查找的实际对象。即使是好的hashCode
实现也必然会发生无法忽视的冲突。因此,如果这些冲突经常发生,那么具有相同hashCode且不相等的对象可能是糟糕的性能,但它不会破坏语义。另一种方式(具有不同hashCodes的相同对象)确实打破了语义。