HashCode với Equals trong Java
Đầu tiên ta phân biệt giữa equals() và ‘==’.
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. Còn 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.
Ví dụ với so sánh ‘==’:
class Nguoi { String ten; String diaChi; public Nguoi() { super(); } public Nguoi(String ten, String diaChi) { super(); this.ten = ten; this.diaChi = diaChi; } } Nguoi n1 = new Nguoi("tran van a", "ha noi"); Nguoi n2 = new Nguoi("tran van a", "ha noi");
Rõ ràng 2 đối tượng n1 và n2 có các thuộc tính giống hệt nhau, nhưng nếu so sánh n1==n2 sẽ trả về false khác nhau bởi vì khi khởi tạo bằng toán tử new thì n1 và n2 đã được trỏ tới 2 vùng nhớ khác nhau.
Nếu viết:
Nguoi n1 = new Nguoi("tran van a", "ha noi"); Nguoi n2 = n1;
Thì có thể hiểu là n2 đã trỏ tới vùng nhớ của n1 như vậy n1 và n2 có cùng địa chỉ, khi đó so sánh n1==n2 sẽ trả về true.
Đối với các biến nguyên thủy thì khi so sánh ‘==’ nó sẽ so sánh giá trị của chúng, ví dụ int a=10, int b=10 thì a==b sẽ trả về giá trị true, hay String str1=”a” , str2=”abc” thì so sánh str1==str2 sẽ trả về false.
- Vấn đề đặt ra là với những kiểu đối tượng khác như class Nguoi thì việc equals() chúng như nào, 2 đối tượng người bằng nhau dựa trên điều kiện nào?
- hashCode là gì: 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.
Ý nghĩa của hàm hashCode
Ví dụ: ta có class sau
class Nguoi { String ten; String diaChi; public Nguoi() { super(); } public Nguoi(String ten, String diaChi) { super(); this.ten = ten; this.diaChi = diaChi; } @Override public boolean equals(Object obj) { if (obj.getClass() != this.getClass()) return false; Nguoi n = (Nguoi) obj; return this.ten == n.ten; } @Override public int hashCode() { return diaChi.hashCode(); } }
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.
Để định nghĩa 2 đối tượng người bằng nhau ta phải định nghĩa lại hàm equals(), trong ví dụ trên: ta định nghĩa 2 đối tượng bằng nhau nếu chúng cùng có kiểu là người và phải có cùng tên với nhau. Khi đó:
Nguoi n1 = new Nguoi("tran van a", "ha noi"); Nguoi n2 = new Nguoi("tran van a", "ha noi");
Khi đó so sánh n1.equals(n2) sẽ bằng nhau vì n1 và n2 cùng kiểu Nguoi, cùng hashCode (vì có cùng địa chỉ) và có cùng tên.