Equals chỉ đơn giản là để so sánh 2 đối tượng có bằng nhau hay không thôi mà, cứ vậy mà phang thôi chứ có gì mà làm căng lên thế bợn, còn bày vẽ hỏi phải sử dụng Equals như thế nào cho đúng nữa chứ.

Hãy cùng thử đoán kết quả của đoạn chương trình sau:

Và kết quả có như bạn đoán không nhỉ?

À, ai thấy lấn cấn ở @Getter @Setter thì đọc bài này để nắm thêm nhé Lombok – Toy giúp bạn quay tay nhanh gấp 69 lần

Phương thức equals() được định nghĩa trong lớp Lớp Object (lớp cha của tất cả các lớp trong Java).

I. Phương thức equals() trong Java
Khi so sánh hai đối tượng với nhau, Java gọi phương thức equals() của chúng trả về true nếu hai đối tượng bằng nhau hoặc false nếu hai đối tượng là khác nhau.

Lưu ý: phép so sánh sử dụng phương thức equals() so với sử dụng toán tử == là khác nhau. Phương thức equals() được thiết kế để so sánh hai đối tượng về mặt giá trị ngữ nghĩa (bằng cách so sánh các thành viên dữ liệu của lớp), trong khi toán tử == so sánh hai đối tượng về mặt kỹ thuật (bằng cách so sánh các tham chiếu của chúng, nghĩa là địa chỉ bộ nhớ).

  1. Phương thức equals() của đối tượng String
    Phương thức equals() so sánh hai chuỗi đưa ra dựa trên nội dung của chuỗi. Nếu hai chuỗi khác nhau nó trả về false. Nếu hai chuỗi bằng nhau nó trả về true. Cùng đoán kết quả của chương trình dưới đây nhé.

Kết quả:

Ví dụ kinh điển đó là so sánh chuỗi trong Java, để thấy sự khác nhau giữa phương thức equals() và toán tử ==.

Kết quả:

So sánh tham chiếu (toán tử ==) trả về false vì s1, s2 và s3 là ba đối tượng khác nhau được lưu trữ ở các vị trí khác nhau trong bộ nhớ. Trong khi so sánh ngữ nghĩa trả về true bởi vì s1 và s2 có cùng giá trị (“This is a string”) có thể được coi là bằng nhau về mặt giá trị.

2. Ghi đè phương thức equals() của một Object.

Quay lại với đối tượng Student ở đầu bài viết, ta thấy studentA studentC mặc dù là cùng 1 người (cùng studentId) nhưng khi sử dụng equals() thì cho ra kết quả là false. Trong thực tế, chúng ta có thể xem xét hai đối tượng Student có giá trị ngữ nghĩa tương đương nhau nếu chúng có cùng thuộc tính (id, name, và age). Vậy nên chúng ta cần phải ghi đè lại phương thức equals() của đối tượng Student. Bây giờ, hãy xem cách ghi đè phương thức equals() trong lớp này để xác nhận rằng hai đối tượng Student có các thuộc tính giống nhau được coi là bằng nhau:

Và đây là sự khác biệt so với đáp án ở đầu bài viết.

II. Phương thức hashCode() trong Java
Định nghĩa phương thức hashCode() trong lớp Object:

Đây là phương thức được sử dụng để trả về giá trị hashcode được liên kết với object. Giá trị hashcode là một số nguyên được liên kết với mỗi object. Nó được sử dụng để xác định vị trí của các đối tượng trong hashtable (bảng băm).

Chúng ta sẽ cùng xem kết quả trả về của hashCode() thông qua đối tượng Student.

Chúng ta sử dụng lại lớp Student MainStudent ở bên trên nhé, và đây là kết quả

Các đối tượng như HashMap, HashTable sử dụng các đối tượng key để tìm kiếm các đối tượng value tương ứng (key-value). Và để tối ưu cho việc tìm kiếm, Java sử dụng các hash value lấy từ phương thức hashCode() của các đối tượng key để gom nhóm các đối tượng này trong những cái gọi là các bucket (Bucket là nơi mà chúng ta lưu trữ các cặp key-value). Mỗi bucket tương ứng với một giá trị hash value.

Khi tìm kiếm một đối tượng bất kỳ trong HashMap hay HashTable, đầu tiên Java sẽ lấy hash value của đối tượng key mà chúng ta muốn tìm kiếm. Sau đó nó sẽ kiểm tra các bucket để xem giá trị hash value đó có trùng khớp với bucket nào hay không. Nếu thoả mãn một bucket nào đó thì Java sẽ trả về giá trị của đối tượng value mà chúng ta muốn tìm kiếm.

Nhiều đối tượng có thể có cùng hash value, và do đó chúng có thể nằm chung một bucket. Trong trường hợp này, Java sẽ sử dụng tiếp phương thức equals() để tìm chính xác đối tượng value mà chúng ta muốn tìm kiếm.

Ở đây chúng ta có một khái niệm gọi là contract (bản hợp đồng) giữa phương thức equals() và phương thức hashCode() đó là:
– Nếu hai đối tượng là bằng nhau thì chúng phải có cùng hashCode().
– Nếu hai đối tượng có cùng hashCode() thì chúng có thể bằng nhau hoặc là không.

II. Các điểm Gờ cần chú ý liên quan đến ==, equals và hashCode

  • Toán tử ‘==’ được dùng để so sánh địa chỉ 2 đối tượng và giá trị của các biến nguyên thủy.
  • equals() được dùng để định nghĩa thế nào là 2 đối tượng trùng nhau, equals() chỉ áp dụng cho kiểu đối tượng, không áp dụng cho kiểu nguyên thủy.
  • hashCode có thể hiểu là giá trị định danh cho 1 đối tượng, những đối tượng bằng nhau sẽ có hashCode bằng nhau còn hashCode bằng nhau thì chưa chắc 2 đối tượng đó đã bằng nhau. hashCode trả về của đối tượng người được tạo ra sẽ là mã băm của địa chỉ, như vậy chỉ những đối tượng nào có cùng địa chỉ thì mới có khả năng bằng nhau(chưa chắc đã bằng nhau), còn nếu khác địa chỉ thì chắc chắn sẽ khác nhau.
  • Để kiểm tra 2 đối tượng có bằng nhau hay không ta phải định nghĩa lại hàm equals() để so sánh tất cả các thuộc tính của 2 đối tượng đó.

Cảm ơn các bạn đã đọc hết bài viết, theo dõi SuSuDev để cập nhật các bài viết mới và thú vị nhé!

Nếu các bạn có bất kỳ thắc mắc hoặc góp ý xin vui lòng để lại bình luận bên dưới nhé!

Cảm ơn các bạn!

Nhớ ghi nguồn https://susudev.com khi đăng tải lại bài viết này