Java中equals()和hashCode()方法之间的约定是什么?

每个Java对象都有两个非常重要的方法equals()hashCode() ,这些方法被设计为根据其特定的常规协定进行覆盖。一个对象类的父类每类的,这两种方法的默认实现已经存在于每个类。但是,我们可以根据需要覆盖这些方法。

hashCode()方法

public int hashCode()

此方法返回一个数值,该值称为对象的哈希码值。每个对象在创建时都分配有一个唯一的32位带符号的int值。该值是该对象的哈希码值。

hashCode()方法相关的总合同

  • 对于该方法的每次调用,除非修改存储在对象中的值,否则 hashCode()方法应针对同一对象返回相同的整数值。

  • 如果两个对象相等(根据equals()方法),则hashCode()方法应为两个对象返回相同的整数值。

  • 但是,没有必要 hashCode()方法将为不相等的对象返回不同的结果(根据equals()方法)。

equals()方法

public boolean equals(Object obj)

Object类的equals()方法检查对象的相等性,并因此返回truefalse。Object类提供的默认实现根据两个引用是否引用同一个对象来检查对象的相等性。它不检查对象的值或状态。但是我们可以重写此方法,以提供自己的实现来比较对象的状态或值。

equals()方法相关的总合同

对于任何非空引用变量a,b和c

  • a.equals(a)应该始终返回true

  • a.equals(B)应该返回当且仅当b.equals(一)返回true。

  • 如果a.equals(b)返回true,b.equals(c)返回true,a.equals(c)应该返回true

  • 如果未针对任何一个对象修改对象的值,则多次调用a.equals(b)应该始终返回true或始终返回false

  • a.equals(null)应该返回false

因此,如果我们要重写equals()方法,则必须重写Object类的hashCode  ()方法。

示例

public class MainClass {
   public static void main(String[] args) {
      MainClass mainClass = new MainClass();
      TestClass obj1 = new TestClass(1);
      TestClass obj2 = new TestClass(1);
      mainClass.test1(obj1, obj2);
      TestClass obj3 = new TestClass(1);
      TestClass obj4 = new TestClass(2);
      mainClass.test2(obj3, obj4);
   }
   public void test1(TestClass obj1, TestClass obj2) {
      if (obj1.equals(obj2)) {
         System.out.println("Object One and Object Two are equal");
      }
      else {
         System.out.println("Object One and Object Two are not equal");
      }
   }
   public void test2(TestClass obj3, TestClass obj4) {
      if (obj3.equals(obj4)) {
         System.out.println("Object Three and Object Four are equal");
      }
      else {
         System.out.println("Object Three and Object Four are not equal");
      }
   }
}
class TestClass {
   private int val;
   TestClass(int val) {
      this.val = val;
   }
   public int getValue() {
      return val;
   }
   @Override
   public boolean equals(Object o) {
      //空检查
      if (o == null) {
         return false;
      }
      //这个实例检查
      if (this == o) {
         return true;
      }
      //instanceof检查和实际值检查
      if ((o instanceof TestClass) && (((TestClass) o).getValue() == this.val)) {
         return true;
      }
       else {
         return false;
      }
   }
   @Override
   public int hashCode() {
      int result = 0;
      result = (int) (val / 11);
      return result;
   }
}

输出结果

Object One and Object Two are equal
Object Three and Object Four are not equal