hashcode()和equals()方法

san*_*iee 10 java equals hashcode hashset

所以我对hashcode()和equals()方法有疑问

假设我只是写了一个非常基本的程序来覆盖这两个方法

import java.util.*;

class Employee
{
   private String name;
   private int empid;


   public Employee(String name,int empid)
   {
       this.name=name;
       this.empid=empid;
   }


   public int getEmpid()
   {
       return empid;
   }


   public String getName()
   {
       return name;
   }


   public boolean equals(Object obj)
   {
       System.out.println("equals has just been called...");
       Employee e1=(Employee)obj;
       return ((name.equals(e1.name)) && (empid==e1.empid));
   }


   public int hashCode()
   {
       System.out.println("hashcode called...");
       return empid;
   }

}
Run Code Online (Sandbox Code Playgroud)

然后,假设我编写了另一个类来添加和迭代HashSet中的元素

class Five
{
   public static void main(String args[])
   {
       HashSet hs1=new HashSet();
       hs1.add(new Employee("Alex",25));
       hs1.add(new Employee("Peter",25));
       hs1.add(new Employee("Martin",25));
       hs1.add(new Employee("Alex",25));


       Iterator itr=hs1.iterator();

       while(itr.hasNext())
       {
           Employee e=(Employee)itr.next();
           System.out.println(e.getEmpid()+"\t"+e.getName());
       }


    }

}
Run Code Online (Sandbox Code Playgroud)

现在问题是当我尝试再次使用相同的empid添加Alex时,equals()总是称为thee次

因为没有索引n hashmap所以如果首先用先前添加的Alex检查它将返回true并且不应该为其他两个元素(peter和martin)调用但是equals总是被调用3次

为什么..??

是同一个桶内的对象也有索引.. ??

Jun*_*san 12

EqualshashCode在添加和删除元素时,始终在java哈希集合中的方法之后调用.原因是,如果已经存在指定存储桶的元素,则JVM会检查它是否与它尝试放置的元素相同.如果equals返回false,则该元素将添加到同一个存储桶中,但位于存储桶列表的末尾.所以现在你只是在同一个桶中没有一个元素,而是一个元素列表.

现在,在检索元素时,将调用第一个hashCode以到达所需的存储桶,然后使用等于扫描列表以获取所需的元素.

理想的实现hashCode将确保每个桶的列表大小为1.因此,元素的检索是使用O(1)复杂度完成的.但是如果在桶中的列表中存储了多个元素,那么元素的重新定位将由O(n)复杂完成,其中n是列表的大小.

顺便说一下,在HashSet的情况下,没有在桶中创建列表,而是如果hashcode和equals相同则简单地替换对象.ist创建行为在hashmap中.

  • 我认为hashCode-method调用后跟equals-method调用... (2认同)
  • @JunedAhsan完全正确.我不是英语母语人士,但不应该是"hashCode后跟等号"吗? (2认同)