Есть ли способ вручную перефразировать карту в Java? - PullRequest
1 голос
/ 09 октября 2019

У меня есть класс 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, поэтому нет никаких ограничений в том, как решить эту проблему.

1 Ответ

1 голос
/ 09 октября 2019

Я думаю, что empId может однозначно идентифицировать сотрудника.

, поэтому метод 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());
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...