如果我有一个employee类作为hashMap的键,并且我使用id字段覆盖employee-equals函数,使用name字段覆盖hashcode函数。会发生什么?
假设您的Map中有一个Employee。现在假设Employee结婚并更改了她的姓氏。现在,该Employee的hashCode
发生了更改。map.get()
在HashMap的不同bin中查找该Employee(由于hashCode更改(,但没有找到它。
结论-equals
和hashCode
都应该使用Employee ID。
请注意,这里的问题源于您选择了一个可变字段(假设名称是可变的(来计算您的hashCode,而不是严格地使用不同的字段来计算hashCode和equals。
hashCode
合同的一部分说
如果根据equals(Object(方法,两个对象相等,那么对这两个对象中的每一个调用hashCode方法必须产生相同的整数结果。
所以,如果你没有任何的情况
- 两个
Employee
对象具有相同的id,但名称不同,或者 - CCD_ 7对象改变其名称
那你就没事了。
事实上,您的建议听起来非常合理,当然前提是id
值在您将存储在地图中的所有员工中都是唯一的。
以下是一些场景,如果您使用empName覆盖哈希代码,并使用empId覆盖equals,则可能会发生这种情况。
注意:下面的hashcode和equals方法的实现是根据问题的要求完成的。
员工.java
public class Employee {
private String empId;
private String empName;
public Employee(String empId, String empName) {
super();
this.empId = empId;
this.empName = empName;
}
@Override
public int hashCode() {
return empName.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
Employee employee = (Employee) obj;
return this.empId.equals(employee.empId);
}
@Override
public String toString() {
return "Employee [empId=" + empId + ", empName=" + empName + "]";
}
}
TestHashCode.java
public class TestHashCode {
public static void main(String[] args) {
HashMap<Employee, String> map = new HashMap<Employee, String>();
/**
* Below two object are unequal by equals method and have same hash
* code. Both employee1 & employee2 will be stored in same bucket
* Corresponding to hash code in a linked list.
*/
Employee employee1 = new Employee("123", "abc");
Employee employee2 = new Employee("124", "abc");
map.put(employee1, "abc");
map.put(employee2, "xyz");
// output:Collosionresult:abc,xyz
System.out.println("Collosionresult:" + map.get(employee1) + ","
+ map.get(employee2));
/**
* Below two object are equal by equals method and have same hash code.
* Value will be overridden. Meaning both employee3 & employee4 will get
* the same value ie. the most recently updated value(world).
*/
Employee employee3 = new Employee("hello", "pqr");
Employee employee4 = new Employee("hello", "pqr");
map.put(employee3, "hello");
map.put(employee4, "world");
//Output:OverriddenResult:world,world
System.out.println("OverriddenResult:" + map.get(employee3) + ","
+ map.get(employee4));
}
hashCode的一般合同是:
每当在Java应用程序的执行过程中对同一对象多次调用hashCode方法时,hashCode方法必须
一致地返回相同的整数,前提是在修改对象上的equals比较。此整数不需要
从应用程序的一次执行到另一次执行保持一致
执行相同的应用程序。如果根据equals(Object(方法,两个对象相等,则必须对这两个对象中的每一个调用hashCode方法产生相同的整数结果。
如果根据equals(java.lang.Object(方法,两个对象不相等,则不需要调用
上的hashCode方法这两个对象中的每一个都必须产生不同的整数结果
然而,程序员应该意识到,产生明显的
不相等对象的整数结果可以提高
的性能哈希表。