Hashcode 等于合同失败但 HashMap 有效
Hashcode Equals Contract failed but HashMap works
我发现了以下关于 OCPJP 的问题:
class Student{
public Student(int r) {
rollNo = r;
}
int rollNo;
public int hashCode(){
return rollNo;
}
}
class Test {
public static void main(String[] args){
HashSet<Student> students = new HashSet<>();
students.add(new Student(5));
Student s10 = new Student(10);
students.add(s10);
System.out.println(students.contains(new Student(10)));
System.out.println(students.contains(s10));
}
}
输出是:
错误的
真
您甚至可以从一组中成功删除 s10。
如果 equals 没有被覆盖,这怎么会起作用?
如果你不覆盖equals
,那么它实际上会检查被比较的两个对象在内存中是否相同。由于您实际上是在检查 s10
自身,因此标准 equals
的计算结果为 true
因为它是同一个对象。
这是 contains
that explains this 上的文档:"Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e))
."
并且,对于 Object.equals
:"The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true)."
默认的 equals
方法等同于 ==
,因此对于 s10.equals(s10)
它将 return 为真,默认的 hash
方法将始终 return 与 s10
.
相同的值
所以默认情况下,只要您添加、检查和删除同一个物理对象,HashSet
就会起作用。
这通常没有用,因为您经常会丢失对原始密钥的引用,并且将构建一个新密钥(但如果您使用常量密钥,只要您在相同的类加载器)。
我发现了以下关于 OCPJP 的问题:
class Student{
public Student(int r) {
rollNo = r;
}
int rollNo;
public int hashCode(){
return rollNo;
}
}
class Test {
public static void main(String[] args){
HashSet<Student> students = new HashSet<>();
students.add(new Student(5));
Student s10 = new Student(10);
students.add(s10);
System.out.println(students.contains(new Student(10)));
System.out.println(students.contains(s10));
}
} 输出是: 错误的 真
您甚至可以从一组中成功删除 s10。 如果 equals 没有被覆盖,这怎么会起作用?
如果你不覆盖equals
,那么它实际上会检查被比较的两个对象在内存中是否相同。由于您实际上是在检查 s10
自身,因此标准 equals
的计算结果为 true
因为它是同一个对象。
这是 contains
that explains this 上的文档:"Returns true if this set contains the specified element. More formally, returns true if and only if this set contains an element e such that (o==null ? e==null : o.equals(e))
."
并且,对于 Object.equals
:"The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true)."
默认的 equals
方法等同于 ==
,因此对于 s10.equals(s10)
它将 return 为真,默认的 hash
方法将始终 return 与 s10
.
所以默认情况下,只要您添加、检查和删除同一个物理对象,HashSet
就会起作用。
这通常没有用,因为您经常会丢失对原始密钥的引用,并且将构建一个新密钥(但如果您使用常量密钥,只要您在相同的类加载器)。