hashCode和Equals在Map键中无法正常工作

时间:2014-09-11 05:51:54

标签: java override equals hashcode

我有Employee类,并希望将此类用作HashMap中的键,该映射的值将是一个字符串。但是,要实现这一点,我已经在Employee类本身中重写了equals和hashcode方法。我有另一个类来测试Employee类键是否能正常工作。经过测试,我发现地图正在存储重复的密钥。请在下面找到源代码和输出:

Employee.java

public class Employee {

    private int empId;
    private String empName;
    private int empAge;

    Employee(){}

    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;
    }

    public int getEmpAge() {
        return empAge;
    }

    public void setEmpAge(int empAge) {
        this.empAge = empAge;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj == null) return false;
        if(!(obj instanceof Employee)) return false;

        Employee e = (Employee)obj;

        return e.empId == this.empId;
    }

    @Override
    public int hashCode() {
        return this.empId;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "Id : "+empId+" Name : "+empName+" Age : "+empAge;
    }
}

TestEmployee.java

import java.util.HashMap;
import java.util.Map;


public class TestEmployee {

    /**
     * @param args
     */
    public static void main(String[] args) {

        Map<Employee, String> empMap = new HashMap<Employee, String>();

        Employee emp1 = new Employee();
        emp1.setEmpId(10);
        emp1.setEmpName("A");
        emp1.setEmpAge(20);

        Employee emp2 = new Employee();
        emp2.setEmpId(20);
        emp2.setEmpName("B");
        emp2.setEmpAge(21);

        empMap.put(emp1, "1");
        empMap.put(emp2, "2");

        System.out.println(empMap);

        emp1.setEmpId(20);

        System.out.println(" emp1.equals(emp2) : "+emp1.equals(emp2));
        System.out.println(" emp1.hashCode() : "+emp1.hashCode()+" emp2.hashCode() : "+emp2.hashCode());

        System.out.println(empMap);

    }

}

输出:

{Id : 20 Name : B Age : 21=2, Id : 10 Name : A Age : 20=1}
 emp1.equals(emp2) : true
 emp1.hashCode() : 20 emp2.hashCode() : 20
{Id : 20 Name : B Age : 21=2, Id : 20 Name : A Age : 20=1}

请告诉我如何在地图密钥中使用唯一的员工 - 唯一性将根据员工ID决定。

2 个答案:

答案 0 :(得分:3)

当对象在hashmap中时,更新用于hashcode的值。哈希码将用于决定放置对象的位置。如果您之后更新,则此更新不会被选中&#34;通过hashmap,所以最多你有重复项,最坏的情况是你不能再检索连接到更新键的值。

<强>更新

请检查javadoc以获取更多信息,但是高级别HashMap会根据密钥的哈希码选择一个存储桶来放入值。如果您尝试使用密钥检索该值,它将查看密钥的哈希码,确定它应该位于哪个桶中,然后检查该桶并检索该值。

但是如果在put()和get()之间键的哈希码发生了变化,那么hashmap可能会把它放在桶中,而#34; A&#34;并尝试将其放入桶中&#34; B&#34;。

答案 1 :(得分:0)

在您的equals方法中,而不是使用&#39; ==&#39;参考比较使用equals方法 as&#39; ==&#39;比较检查参考相等而不是值比较。 的像 return e.empId.equals(this.empId);

Java Integer类正确覆盖equals,它将为您提供正确的结果。