我有Employee两个属性的类。
public class Employee {
private int empId;
private String empName;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return getEmpId() == employee.getEmpId() &&
Objects.equals(getEmpName(), employee.getEmpName());
//return Objects.equals(getEmpName(), employee.getEmpName());
}
@Override
public int hashCode() {
//return Objects.hash(getEmpId());
return Objects.hash(getEmpId(), getEmpName());
}
} 我正在使用此类作为Hashmap中的键。
现在,当emp在这种情况下修改Employee对象的名称时修改原始对象时,我无法访问我最初保存在地图中的条目。只有当我将名称回滚到原始值时,我才能再次访问该对象。
这表明我在Employee对象中更改名称时,其哈希值已更改,并且未存储在Hashmap的正确存储区下。
Map<Employee, String> map = new HashMap<>();;
// Set Employee with Name Shashi
Employee emp = new Employee();
emp.setEmpId(1);
emp.setEmpName("Shashi");
// Add to Map
map.put(emp, emp.getEmpName());
// Modify The Original Employee object's Name
emp.setEmpName("Shashi Bhushan");
// This object does not exist as key in map now
Assert.assertFalse(map.containsKey(emp));
// Create object with same name(used when creating)
Employee similarEmployee = new Employee();
similarEmployee.setEmpId(1);
similarEmployee.setEmpName("Shashi");
// Hashcode check will pass, equals will fail
Assert.assertFalse(map.containsKey(similarEmployee));
Assert.assertNull(map.get(similarEmployee));
// Create object with same name(modified name)
Employee anotherSimilarEmployee = new Employee();
anotherSimilarEmployee.setEmpId(1);
anotherSimilarEmployee.setEmpName("Shashi Bhushan");
// Hashcode check will fail
Assert.assertFalse(map.containsKey(anotherSimilarEmployee));
Assert.assertNull(map.get(anotherSimilarEmployee));
// Now, if I roll back the name, i could again fetch using the new created object as well.
// Since now this new object will be equivalent to the old object.
emp.setEmpName("Shashi");
Assert.assertTrue(map.containsKey(similarEmployee));
Assert.assertNotNull(map.get(similarEmployee));
能够获取map中对象的问题的一种解决方案是使Employee类不可变。
我能想到的另一种理论解决方案是重新散列地图并将修改后的Employee对象保留在地图的正确存储区中,但我看不到哈希图中的任何方法来对其进行散列。
我认为只有empId可以识别employee。 所以equals和hashCode方法只需要处理empId字段: @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Employee)) return false; Employee employee = (Employee) o; return getEmpId() == employee.getEmpId()); }
@Override
public int hashCode() {
return Objects.hash(getEmpId());
}
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。