Java 重写哈希代码时要记住的事项

Java 重写哈希代码时要记住的事项,java,Java,Person类中hashCode方法的适当定义是什么 A.返回super.hashCode() B.返回name.hashCode()+年龄*7 C.返回name.hashCode()+comment.hashCode()/2 D.返回name.hashCode()+comment.hashCode()/2-age*3 答案是B 有人能解释一下为什么C和D是错的吗?粗略阅读。由于equal()方法考虑了这两个变量(即名称和年龄),因此B似乎是更好的方法。equals方法说,当对象具有相同的名称和

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

A.返回super.hashCode()
B.返回name.hashCode()+年龄*7
C.返回name.hashCode()+comment.hashCode()/2
D.返回name.hashCode()+comment.hashCode()/2-age*3

答案是B


有人能解释一下为什么C和D是错的吗?

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

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

equals和hashCode的契约要求两个相等的对象具有 相同的哈希代码


C和D可能违反此规则,因为具有相同名称和年龄但注释不同的对象会产生不同的哈希代码。

对于A、C和D,
hashCode()
可能会为
Person
的两个实例返回不同的结果,其
equals()
方法返回
true
,也就是说,两个相等的
Person
s可能返回不同的散列码

这显然违反了公司的合同:

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

对于C和D,如果两个人年龄和姓名相同,但注释不同,
equals()
将返回
true
,而
hashCode()
将产生不同的值

对于A,由于
Person
隐式地从
对象
类派生(即,它不从任何显式超类扩展),因此
super.hashCode()
的结果只有在同一实例上调用时才会相等。根据
Object.hashCode()
docs:

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

因此,如果您有两个不同的
Person
类实例,它们都具有相同的名称、年龄和注释,
equals()
将返回
true
,而
hashCode()
将返回不同的值,违反了
hashCode()
的约定


实际上,这意味着
Person
类不能是任何
Map
的键

您可以使用这些hashcode方法中的任何一种(A可能不会给出很好的结果),但B是最简单的方法。@JonasCz和D是错误的,因为它们与equalsGood解释不一致!:)
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);
    }
}