重写hashCode时要记住的事情

时间:2015-03-29 15:56:04

标签: java

public class Person {
    private String name, comment;
    private int age;

    public Person(String n, int a, String c) {
        name = n;
        age = a;
        comment = c;
    }

    public boolean equals(Object o) {
        if (!(o instanceof Person))
            return false;
        Person p = (Person) o;
        return age == p.age && name.equals(p.name);
    }
}
  

Person类中hashCode方法的适当定义是什么?

     

一个。 return super.hashCode();
  B.返回name.hashCode()+ age * 7;
  C. return name.hashCode()+ comment.hashCode()/ 2;
  D. return name.hashCode()+ comment.hashCode()/ 2 - age * 3;

答案是 B

有人可以解释一下,为什么C和D都错了?

3 个答案:

答案 0 :(得分:8)

对于A,C和D,hashCode()可能会为Person方法返回equals()的{​​{1}}个实例返回不同的结果,即两个true相同的s可能会返回不同的哈希码。

这显然违反了Object.hashCode()的合同:

  

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

对于C和D,如果两个Person具有相同的年龄和名称但评论不同,Person将返回equals(),而true会产生不同的值。

对于A,因为hashCode()隐式地从Person类下降(即它不从任何显式超类扩展),Object的结果仅在调用时才相等相同的实例。根据{{​​1}}文档:

  

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但Java™编程语言不需要此实现技术。)

因此,如果您有两个super.hashCode()类的不同实例,两个具有相同的名称,年龄和评论,Object.hashCode()将返回Person,而equals()则会返回不同的值,违反了true的合同。

实际上,这意味着hashCode()类不能成为任何hashCode()的关键。

答案 1 :(得分:4)

equals方法表示当对象具有相同的名称和年龄时,它们是相同的。这些评论不会影响到这里的平等。

equals和hashCode的契约要求2个相等的对象具有 相同的hashCode。

C和D可能违反此规则,因为具有相同名称和年龄但不同注释的对象会导致不同的hashCodes。

答案 2 :(得分:2)

从粗略阅读。似乎B是更好的因为equal()方法考虑了这两个变量(名称和年龄)。