Hashcode Equals Contract失败但HashMap工作正常

时间:2015-02-23 16:03:36

标签: equals hashcode

我找到了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。 如果没有覆盖等于,这怎么工作?

2 个答案:

答案 0 :(得分:1)

如果你不覆盖equals,那么它基本上会检查被比较的两个对象在内存中是否相同。由于您实际上是针对自身检查s10,因此标准equals评估为true,因为它是同一个对象。

这是contains that explains this上的文档:“如果此集合包含指定的元素,则返回true。更正式地,当且仅当此集合包含元素e (o==null ? e==null : o.equals(e))时才返回true。”

并且,对于Object.equals:“类Object的equals方法实现了对象上最具辨别力的可能等价关系;也就是说,对于任何非空引用值x和y,此方法仅返回true如果x和y引用同一个对象(x == y的值为true)。“

答案 1 :(得分:1)

默认的equals方法相当于==,因此它会为s10.equals(s10)返回true,默认的hash方法将始终返回{{1}的相同值}}

因此,默认情况下,只要您添加,检查和删除相同的物理对象,s10就会起作用。

这通常不常用,因为你经常会丢失对原始键的引用并且将构造一个新键(但是如果你使用常量键,只要你在同一个类加载器中它就可以工作)。