equals() và hashCode(): vì sao phải override cùng nhau
22/07/2026
Trong Java, equals() và hashCode() là một cặp không thể tách rời. Override cái này mà quên cái kia là lỗi âm thầm gây bug khó lần trong HashMap, HashSet.
Hợp đồng bắt buộc
- Nếu hai object
equalsnhau thìhashCodecủa chúng PHẢI bằng nhau - Ngược lại không bắt buộc: cùng hashCode không nhất thiết equals (được phép va chạm hash)
- hashCode phải nhất quán trong một lần chạy nếu object không đổi
Hậu quả khi vi phạm
HashMap tìm bucket bằng hashCode trước, rồi so equals trong bucket. Nếu override equals nhưng để nguyên hashCode mặc định (dựa trên địa chỉ bộ nhớ), hai object 'bằng nhau' rơi vào bucket khác nhau — map.get(key) trả về null dù key đã tồn tại.
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User u)) return false;
return Objects.equals(id, u.id);
}
@Override public int hashCode() {
return Objects.hash(id);
}
Mẹo an toàn
- Dùng cùng bộ field cho cả equals và hashCode
- Dùng
Objects.equals/Objects.hashđể khỏi tự xử lý null - Với record, compiler tự sinh đúng cặp này — một lý do nữa để dùng record cho value object
👉 Dùng thử công cụ liên quan trên dev-hub: JSON Formatter — chạy hoàn toàn trong trình duyệt, không gửi dữ liệu lên server.