如果equals和hashcode比较hashmap中的不同值会怎么样?

时间:2015-07-05 03:41:26

标签: java hashmap

如果我有一个employee类作为hashMap的键,我使用id字段和hashcode函数使用name字段覆盖employee equals函数。会发生什么?

3 个答案:

答案 0 :(得分:3)

假设您的地图中有一名员工。现在假设员工结婚并改变她的姓氏。现在,该员工的hashCode发生了变化。 map.get()在HashMap的不同bin中查找Employee而不是它所在的bin(由于hashCode更改),并且找不到它。

结论 - 您应该使用equalshashCode的员工ID。

请注意,这里出现的问题是您选择了一个可变字段(假设名称是可变的)来计算您的hashCode,而不是严格地使用不同的字段来计算hashCode和equals。

答案 1 :(得分:1)

hashCode合同的一部分

  

如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须产生相同的整数结果。

所以,如果你没有任何

的情况
  • 两个Employee个对象具有相同的ID,但名称不同,或者
  • Employee对象更改其名称

那你就没事了。

事实上,您提出的建议听起来非常合理,当然,id值是唯一的,而您将在地图中存储的所有员工。

答案 2 :(得分:0)

以下是一些情况,如果您使用empName覆盖哈希码并使用empId等于。

注意:hashcode和equals方法的以下实现是根据问题的要求完成的。

<强> Employee.java

public class Employee {
    private String empId;
    private String empName;

    public Employee(String empId, String empName) {
        super();
        this.empId = empId;
        this.empName = empName;
    }

    @Override
    public int hashCode() {

        return empName.hashCode();
    }

    @Override
    public boolean equals(Object obj) {

        if (obj == null)
            return false;
        Employee employee = (Employee) obj;
        return this.empId.equals(employee.empId);
    }

    @Override
    public String toString() {
        return "Employee [empId=" + empId + ", empName=" + empName + "]";
    }

}

TestHashCode.java

public class TestHashCode {
    public static void main(String[] args) {
        HashMap<Employee, String> map = new HashMap<Employee, String>();

        /**
         * Below two object are unequal by equals method and have same hash
         * code. Both employee1 & employee2 will be stored in same bucket
         * Corresponding to hash code in a linked list.
         */
        Employee employee1 = new Employee("123", "abc");
        Employee employee2 = new Employee("124", "abc");

        map.put(employee1, "abc");
        map.put(employee2, "xyz");
        // output:Collosionresult:abc,xyz
        System.out.println("Collosionresult:" + map.get(employee1) + ","
                + map.get(employee2));

        /**
         * Below two object are equal by equals method and have same hash code.
         * Value will be overridden. Meaning both employee3 & employee4 will get
         * the same value ie. the most recently updated value(world).
         */
        Employee employee3 = new Employee("hello", "pqr");
        Employee employee4 = new Employee("hello", "pqr");
        map.put(employee3, "hello");
        map.put(employee4, "world");
        //Output:OverriddenResult:world,world
        System.out.println("OverriddenResult:" + map.get(employee3) + ","
                + map.get(employee4));          

    }

hashCode的一般合约是:

  
      
  • 每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须为   如果没有使用任何信息,则始终返回相同的整数   等于对象的比较被修改。这个整数不需要
      从一个应用程序的执行到另一个应用程序保持一致   执行相同的申请。

  •   
  • 如果两个对象根据equals(Object)方法相等,则必须对两个对象中的每一个调用hashCode方法   产生相同的整数结果。

  •   
  • 如果两个对象根据equals(java.lang.Object)方法不相等,则不需要调用hashCode方法   两个对象中的每一个都必须产生不同的整数结果   但是,程序员应该意识到产生不同的
      不等对象的整数结果可以提高性能   哈希表。

  •