[英]when do i need hashcode and equals method?
我有哈希集,我会将集合存储到对象,并且我想找到特定的对象,在这种情况下,为什么我需要覆盖从下面的示例中读取的哈希码和equals方法
public class Emp
{
private int age ;
public Emp( int age )
{
super();
this.age = age;
}
public int hashCode()
{
return age;
}
public boolean equals( Object obj )
{
boolean flag = false;
Emp emp = ( Emp )obj;
if( emp.age == age )
flag = true;
return flag;
}
}
他们说如果我不重写哈希码和equals方法,则对于以下查询,我将为假。
System.out.println("HashSet Size--->>>"+hs.size());
System.out.println("hs.contains( new Emp(25))--->>>"+hs.contains(new Emp(25)));
System.out.println("hs.remove( new Emp(24)--->>>"+hs.remove( new Emp(24));
System.out.println("Now HashSet Size--->>>"+hs.size());
我感到困惑这与哈希码有什么关系,等于只检查hashset中的contains(anyobject)和remove(anyobject)。
有人可以向我解释以上情况吗?
混淆的基础是身份与平等的概念,以及集合中包含元素的含义。 让我尝试解释一下。
假设您已在代码中的某个位置完成了此操作:
HashSet<Emp> hs = new HashSet<>();
hs.add(new Emp(32));
在其他地方,您想查看是否有32岁的员工在集合中。 你会怎么做? 您可以考虑一下:
boolean isThere = hs.contains(new Emp(32));
您在这里所做的是创建一个Emp
实例,该实例将32
传递给构造函数,然后将该实例传递给contain()
。
请注意,此实例与添加到集合中时创建的实例不同。 因此,问题是:是否contains()
返回true,因为此实例与您添加的实例相同;还是应该返回false,因为它不是完全相同的实例?
结果取决于为Emp
实现hashCode()
和equals()
方式。 使用默认实现,仅当传递的实例与所包含的实例完全相同时(即使用==
比较传递给contains()
的实例和存储的实例equals()
, equals()
返回true。 在这种情况下,它将返回false
。
要了解hashCode()
,您需要了解HashSet
工作方式。 将元素添加到HashSet
,将使用hashCode() % <size of the array>
从该元素计算数组中的索引。 然后将该元素设置为相应索引处的值。
由于不同的元素可能最终具有相同的hashCode()
,因此可以在相同的索引处映射更多的元素,在这种情况下,将保留冲突列表。
因此,回到您的情况,为什么需要实现hashCode()
? 因为默认的实现将为Ent
不同实例返回不同的数字,但age
可能是相同的(实现取决于JVM,例如,它可以返回实例内存中的地址)。 因此,为了使包含工作,我们需要确保为两个实例计算出数组中的相同索引,因此您需要相应地实现它。 例如,在这种情况下, hashCode()
可以返回年龄本身。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.