Java 中的 equals() 和 hashCode() 方法之间的契约是什么?\
javaobject oriented programmingprogramming更新于 2024/7/26 23:50:00
每个 Java 对象都有两个非常重要的方法 equals() 和 hashCode() ,这些方法旨在根据其特定的一般契约进行覆盖。Object 类是每个类的父类,这两个方法的默认实现已经存在于每个类中。但是,我们可以根据需要覆盖这些方法。
hashCode() 方法
public int hashCode()
此方法返回一个整数值,该值称为对象的哈希码值。每个对象在创建时都分配有一个唯一的 32 位有符号 int 值。此值是该对象的哈希码值。
与 hashCode() 方法相关的一般约定
- 除非对象中存储的值被修改,否则 hashCode() 方法在每次调用此方法时都应为同一对象返回相同的整数值。
- 如果两个对象相等(根据 equals() 方法),则 hashCode() 方法应为这两个对象返回相同的整数值。
- 但是, hashCode() 方法不一定会为不相等的对象返回不同的结果(根据 equals() 方法)。
equals() 方法
public boolean equals(Object obj)
Object 类的 equals() 方法检查对象的相等性,并据此返回 true 或 false。Object 类提供的默认实现根据两个引用是否指向同一个对象来检查对象的相等性。它不检查对象的值或状态。但是我们可以重写此方法以提供自己的实现来比较对象的状态或值。
与 equals() 方法相关的一般约定
对于任何非空引用变量 a、b 和 c
- a.equals(a) 应始终返回 true。
- a.equals(b) 应返回 true,当且仅当 b.equals(a) 返回 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) { // null check if (o == null) { return false; } // this instance check if (this == o) { return true; } // instanceof Check and actual value check 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