← Tất cả bài viết

equals() và hashCode(): vì sao phải override cùng nhau

22/07/2026

Trong Java, equals()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

  1. Nếu hai object equals nhau thì hashCode của chúng PHẢI bằng nhau
  2. 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)
  3. 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.