等式测试(等于和哈希码方法)

时间:2011-03-30 05:02:35

标签: java

根据以下链接

Hashcode and equals

因此假设如果2个对象相等(即equals()返回true),则它们的hashCodes()必须返回相同的值。

但请考虑以下示例

public class Test {

    public static void main(String args[]) {
        Demo d1 = new Demo(123);
        Demo d2 = new Demo(123);

        System.out.println("d1.hashCode()-->" + d1.hashCode());
        System.out.println("d2.hashCode()-->" + d2.hashCode());
        System.out.println(d1.equals(d2));
    }
}

class Demo {

    private int name;

    Demo(int name) {
        this.name = name;
    }
    @Override
    public int hashCode() {
        Double d = Math.random() * 1000;
        return d.intValue();
    }
    @Override
    public boolean equals(Object o) {
        if ((o instanceof Demo) && (((Demo) o).getName() == this.getName())) {
            return true;
        } else {
            return false;
        }
    }
    public int getName() {
        return name;
    }
}

上述程序的输出是

  

d1.hashCode() - &加热至85

     

d2.hashCode() - > 692

     

这里的问题是即使哈希码不同,equals方法返回true。 那么对于对象的相等性是否意味着我们不需要相同的哈希码

6 个答案:

答案 0 :(得分:4)

某些实现(例如HashMap)取决于当两个实例相等时它们的哈希码应该相同的事实。但是,纯粹使用equals不会检查这些实例的哈希码。

在散列映射的情况下,首先根据对象的哈希码将元素划分为不同的散列桶(出于性能原因)。在桶内,equals用于检查对象的相等性。如果两个相等的实例不具有相同的hashCode,则它们将以不同的存储桶结束,而可能会因违反合同而导致意外行为。

答案 1 :(得分:3)

hashCode()执行不好,你应该遵守那份合同。

equalshashcode无关。

但是当你使用散列数据结构时,应该必须遵循这个东西。

答案 2 :(得分:1)

你应该从不使用随机数来实现hashCode!它应始终使用与equals使用的相同字段计算。否则,您的对象将无法用作HashMapHashSet

中的键

答案 3 :(得分:1)

实际上,我们的想法是,当您实施equals方法时,您应该实施hashCode方法,如果是a.equals(b)a.hashCode() == b.hashCode()。虽然Java编译器或运行时中没有任何内容可以强制执行此操作。

答案 4 :(得分:0)

在Hashcode中,总是要求如果两个对象相等,那么它们的hashCode总是必须与散列集合相同(HashMap,HashSet等不能正常工作)

在你的情况下,其中一个实现可以是 -

public int hashCode() {
    return this.getName();
}

或者如果你想把它混合一点 -

public int hashCode() {
    return String.valueOf(this.getName()).hashCode();
}

答案 5 :(得分:0)

首先,您不应该使用随机数来实现hashcode()方法。

@Override
public int hashCode() {
    return name.hashcode();
}
@Override
public boolean equals(Object o) {
    if(o !=null && o instanceOf Demo)
    {
        Demo d=(Demo) o;
        if(this.d.name==d.name)
        {
            return true;
        }
        else
        {
            false;
        }
        else
        {
            return false;
        }
    }