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



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

假设您的Map中有一个Employee。现在假设Employee结婚并更改了她的姓氏。现在,该Employee的hashCode发生了更改。map.get()在HashMap的不同bin中查找该Employee(由于hashCode更改(,但没有找到它。

结论-equalshashCode都应该使用Employee ID。

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

hashCode合同的一部分说

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

所以,如果你没有任何的情况

  • 两个Employee对象具有相同的id,但名称不同,或者
  • CCD_ 7对象改变其名称

那你就没事了。

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

以下是一些场景,如果您使用empName覆盖哈希代码,并使用empId覆盖equals,则可能会发生这种情况。

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

员工.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方法时,hashCode方法必须
    一致地返回相同的整数,前提是在修改对象上的equals比较。此整数不需要
    从应用程序的一次执行到另一次执行保持一致
    执行相同的应用程序。

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

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

最新更新