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 就会起作用。

这通常没有用,因为您经常会丢失对原始密钥的引用,并且将构建一个新密钥(但如果您使用常量密钥,只要您在相同的类加载器)。