Same Object用作Map中两个条目的键

Kus*_*thi 2 java object hashmap

我有一个Employee类,如下所示.

class Employee {
int empId;
String empName;

public Employee() {
}

Employee(int empId, String empName) {
    this.empId = empId;
    this.empName = 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 int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + empId;
    result = prime * result + ((empName == null) ? 0 : empName.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Employee other = (Employee) obj;
    if (empId != other.empId)
        return false;
    if (empName == null) {
        if (other.empName != null)
            return false;
    } else if (!empName.equals(other.empName))
        return false;
    return true;
}}
Run Code Online (Sandbox Code Playgroud)

我在这个HashMap中使用这个Employee类对象作为键,如下所示.

    Map<Employee, String> empMap = new HashMap<>();
    Employee e1 = new Employee(123, "xyz");
    empMap.put(e1, "asd");
    System.out.println(empMap.size());
    System.out.println(empMap.get(e1));
    e1.setEmpId(122);
    empMap.put(e1, "asd");
    System.out.println(empMap.size());
    System.out.println(empMap.get(new Employee(122, "xyz")));
    System.out.println(empMap.get(new Employee(123, "xyz")));

    Set<Employee> mapEmpKeys = empMap.keySet();
    mapEmpKeys.forEach(emp -> {
        System.out.println("Employee ID: " + emp.getEmpId() + " Employee Name: " + emp.getEmpName());
    });
Run Code Online (Sandbox Code Playgroud)

计划的输出: 1 asd 2 asd null Employee ID: 122 Employee Name: xyz Employee ID: 122 Employee Name: xyz

我的问题是即使作为键的对象是相同的,我得到的地图大小为2.有人可以解释我,通过将其ID设置为不同的值来更改Employee对象e1,并在地图中再次添加它,给出大小为2当我迭代地图的密钥集时,我得到两个条目的相同对象.键在地图中必须是唯一的,对吧?那为什么我两次获得相同的对象密钥?谢谢!

Era*_*ran 5

当你改变一个用作a中的键的实例时HashMap,如果你修改用于确定相等性的属性或者计算它hashCode(),你就会破坏HashMap.

第一次将密钥放在Map中时,它被放入与hashCode()基于值123和"xyz" 的计算对应的桶中.

第二次将相同的键放在Map中时,它被放入一个不同的桶中,该桶与hashCode()基于值122和"xyz" 的计算值相对应.

由于HashMap首先找到与密钥匹配的存储桶hashCode(),并且稍后只检查该存储桶中的所有密钥以获得密钥相等,如果hashCode()给定密钥的更改,则第二次调用put将尝试在新存储桶中找到它(匹配新的hashCode()) ,并且不会在那里找到它.因此,相同的密钥被添加两次.