У меня есть класс 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, его хеш-код изменяется, и он не сохраняется в правильном сегменте в 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));
Одно из решений для проблемы с возможностью извлечения объектов на карте состоит в том, чтобы сделать класс Employee неизменным.
Другое теоретическое решение, о котором я мог подумать, - это перефразировать карту и сохранить измененный объект сотрудника в правильном месте на карте, но я не смог увидеть ни одного метода в hashmap, который его перефразирует. Пожалуйста, предложите, если я думаю в правильном направлении, или если есть какое-то другое решение для этого.
PS Все это для целей понимания hashmap, поэтому нет никаких ограничений в том, как решить эту проблему.