繁体   English   中英

什么时候需要哈希码和equals方法?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM