HashMap如何识别作为键的自定义Employee类的重复对象?
HashMap中自定义对象作为键的重复判定逻辑
当我们把自定义的Employee类作为HashMap的键使用时,创建两个id均为100但name不同的对象e1和e2,HashMap会将e2判定为重复键还是新增条目?对应的代码如下:
Employee类代码
public class Employee { int id; String 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; } }
测试类代码
public class EmployeeTest { public static void main(String[] args) { Employee e1 = new Employee(); e1.setId(100); e1.setName("abc"); Employee e2 = new Employee(); e2.setId(100); e2.setName("xyz"); Map<Employee, Integer> map = new HashMap<Employee, Integer>(); map.put(e1, 1); map.put(e2, 2); } }
结论与分析
结论:e2不会被判定为重复对象,会在map中新增一条独立的条目
原因很直接:默认情况下Employee继承自Object类,而Object的equals()方法是比较对象的内存地址,hashCode()方法返回的是对象内存地址的哈希值。e1和e2是两个不同的实例,内存地址完全不同,所以HashMap会认为这是两个完全不同的键,因此会新增条目。
如果想要让id相同的Employee对象被视为同一个键,必须在Employee类中重写equals()和hashCode()方法,遵循的核心规则是:
- 两个对象
equals()返回true时,它们的hashCode()必须相等 - 两个对象
hashCode()相等时,equals()不一定需要返回true,但为了HashMap的性能,尽量让hashCode的分布均匀
重写后的Employee类示例:
public class Employee { int id; String 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 boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; return id == employee.id; // 仅以id作为相等判定依据 } @Override public int hashCode() { return Integer.hashCode(id); // 基于id生成哈希值 } }
此时再运行测试代码,e2就会被判定为重复键,map中原来的条目(e1对应的1)会被覆盖为2。
内容的提问来源于stack exchange,提问作者ravi
相关产品推荐
相关产品推荐

