作者:mobiledu2502857377 | 来源:互联网 | 2022-12-18 13:01
我有一个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;
}}
我在这个HashMap中使用这个Employee类对象作为键,如下所示.
Map 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 mapEmpKeys = empMap.keySet();
mapEmpKeys.forEach(emp -> {
System.out.println("Employee ID: " + emp.getEmpId() + " Employee Name: " + emp.getEmpName());
});
计划的输出:
1
asd
2
asd
null
Employee ID: 122 Employee Name: xyz
Employee ID: 122 Employee Name: xyz
我的问题是即使作为键的对象是相同的,我得到的地图大小为2.有人可以解释我,通过将其ID设置为不同的值来更改Employee对象e1,并在地图中再次添加它,给出大小为2当我迭代地图的密钥集时,我得到两个条目的相同对象.键在地图中必须是唯一的,对吧?那为什么我两次获得相同的对象密钥?谢谢!
1> Eran..:
当你改变一个用作a中的键的实例时HashMap
,如果你修改用于确定相等性的属性或者计算它hashCode()
,你就会破坏HashMap
.
第一次将密钥放在Map中时,它被放入与hashCode()
基于值123和"xyz" 的计算对应的桶中.
第二次将相同的键放在Map中时,它被放入一个不同的桶中,该桶与hashCode()
基于值122和"xyz" 的计算值相对应.
由于HashMap
首先找到与密钥匹配的存储桶hashCode()
,并且稍后只检查该存储桶中的所有密钥以获得密钥相等,如果hashCode()
给定密钥的更改,则第二次调用put
将尝试在新存储桶中找到它(匹配新的hashCode()
) ,并且不会在那里找到它.因此,相同的密钥被添加两次.