java - 对象如何存储在 HashMap 中?
问题描述
我对下面的代码感到困惑。当我更改员工 e2 的名称时,我希望地图同时具有 e2 和 e3 对象,因为 e2 对象现在与 e3 不同。但似乎更改 e2 对象的名称并未反映在存储在 hashmap 中的 e2 对象中,因此输出仅显示 e3。所以我很困惑哈希图是存储实际对象还是仅存储原始对象的副本。
代码:
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Employee,Integer> map = new HashMap<Employee,Integer>();
Employee e1 = new Employee(10,"Sachin");
Employee e2 = new Employee(10,"Sachin");
map.put(e1, 1);
map.put(e2,2);
System.out.println(e1.hashCode()+" "+e2.hashCode());
System.out.println(map);
e2.setName("Akshay"); //<---- changing the name for e2
Employee e3 = new Employee(10,"Sachin");
map.put(e3, 3);
System.out.println(map);
}
}
class Employee
{
private int id;
private String name;
public Employee(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.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 (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
输出:
-1826112337 -1826112337
{Employee [id=10, name=Sachin]=2}
{Employee [id=10, name=Sachin]=3}
解决方案
您可能知道,HashMap 中的每个条目都根据其 hashCode() 分配一个存储桶。当条目在 Map 中 put() 时分配存储桶(将项目添加到 HashSet 也是如此)
如果您在放入 Map 后更改键,则 HashMap 不知道此更改。它不会重新计算存储桶并将条目移动到新存储桶(怎么可能?它无法侦听此事件)
根据经验,不要改变 Map 中的键(或 Set 中的项目),因为 Map.containsKey(...) 和 Set.contains(...) 等会出现意外行为。
推荐阅读
- mongodb - 我想知道如何为 Mongo DB 编写更新脚本
- javascript - 在 axios 中出现 SELF_SIGNED_CERT_IN_CHAIN 错误,但通过 curl 或邮递员传递
- sql - RANK() 如何在 Sql 中的多个列上工作?
- amazon-web-services - 设置 AWS S3 存储桶权限
- javascript - 为什么 HTML 属性在 DOM 中设置不同?
- vb.net - VB API 结果转换十进制数
- excel - 用其他工作表中的某些单元格填充列表
- android - 在没有密码的情况下从 AndroidKeyStore 获取 AES 密钥是否不安全?
- crystal-reports - 间距问题 Crystal Reports 2008
- jenkins - Jenkins 工作区是在 master 还是 worker 上?