Mọi đối tượng Java đều có hai phương thức rất quan trọng equals() và hashCode() và các phương thức này được thiết kế để override theo hợp đồng chung cụ thể của chúng. Lớp Object là lớp cha của mọi lớp, triển khai mặc định của hai phương thức này đã có sẵn trong mỗi lớp. Tuy nhiên, chúng ta có thể override các phương thức này dựa trên yêu cầu.
Phương thức hashCode()
public int hashCode()
Phương thức này trả về một giá trị integer, được gọi là giá trị hash code của một đối tượng. Mọi Object, tại thời điểm tạo, được gán một giá trị int 32-bit, signed duy nhất. Giá trị này là hash code của đối tượng đó.
Hợp đồng chung liên quan đến phương thức hashCode()
- Phương thức hashCode() phải trả về cùng một giá trị integer cho cùng một đối tượng cho mỗi lần gọi phương thức này trừ khi giá trị lưu trữ trong đối tượng bị sửa đổi.
- Nếu hai đối tượng bằng nhau (theo phương thức equals()) thì phương thức hashCode() phải trả về cùng một giá trị integer cho cả hai đối tượng.
- Nhưng, không bắt buộc phương thức hashCode() phải trả về kết quả khác biệt cho các đối tượng không bằng nhau (theo phương thức equals()).
Phương thức equals()
public boolean equals(Object obj)
Phương thức equals() của lớp Object kiểm tra sự bằng nhau của các đối tượng và tương ứng nó trả về true hoặc false. Triển khai mặc định, như được cung cấp bởi lớp Object, kiểm tra sự bằng nhau của các đối tượng dựa trên việc cả hai tham chiếu có trỏ đến cùng một đối tượng hay không. Nó không kiểm tra giá trị hoặc trạng thái của các đối tượng. Nhưng chúng ta có thể override phương thức này để cung cấp triển khai riêng để so sánh trạng thái hoặc giá trị của các đối tượng.
Hợp đồng chung liên quan đến phương thức equals()
Đối với bất kỳ biến tham chiếu non-null a, b và c
- a.equals(a) phải luôn trả về true.
- a.equals(b) phải trả về true nếu và chỉ nếu b.equals(a) trả về true.
- Nếu a.equals(b) trả về true và b.equals(c) trả về true thì a.equals(c) phải trả về true.
- Nhiều lần gọi a.equals(b) phải nhất quán trả về true hoặc nhất quán trả về false nếu giá trị của đối tượng không bị sửa đổi cho cả hai đối tượng.
- a.equals(null) phải trả về false.
Vì vậy cần thiết phải override phương thức hashCode() của lớp Object nếu chúng ta override phương thức equals().
Ví dụ
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;
}
}Kết quả
Object One and Object Two are equal Object Three and Object Four are not equal