Tìm hiểu về equals() và hashCode()

I, Phương thức equals()

1, Lý thuyết

  • Như bài viết trước so sánh == và equals(), mình cũng đã nói qua về phương thức equals().
  • Phương thức equals() được dùng để kiểm tra 1 object có equal to với object khác không. Nó được thực thi theo hai cách:
    • Shallow comparison: mặc định, equals() được định nghĩa trong Object class, nó kiểm tra 2 variable có cùng trỏ tới 1 object hay không (tương đương với x == y). Điều này bởi vì Object không có property nào để định nghĩa state.
    • Deep comparison:: class có các property và tiến hành implement equals() method dựa trên các property đó. Ví dụ như Integer, String…
1
2
3
4
5
6
7
8
9
// Shallow comparison
public class Object {

// Not have any member variable to define its state.

public boolean equals(Object obj) {
return (this == obj);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
// Deep comparison
public final class Integer extends Number implements Comparable<Integer> {

private final int value;

public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
}

Chú ý: Nếu class không implement equals() method, equals() của class đó sẽ là của class cha implement equals() gần nó nhất.

2, Ví dụ

  • Ví dụ 1: shallow comparison không override equals() method
1
2
3
4
5
6
7
8
class Test {

public int val;

public Test(int val){
this.val = val;
}
}
1
2
3
4
5
6
7
8
class TestComparator(){

public static void main(String args[]){
Test a = new Test(1000);
Test b = new Test(1000);
a.equals(b) // return false mặc định equals() cũng so sánh memory address (của Object class) như ==.
}
}
  • Ví dụ 2: deep comparison override equals() method
1
2
3
4
5
6
7
8
9
10
11
12
13
class Test {

private int val;

public Test(int val){
this.val = val;
}

// Deep comparison
public boolean equals(Test b){
return this.val == b.val
}
}
1
2
3
4
5
6
7
8
class TestComparator(){

public static void main(String args[]){
Test a = new Test(1000);
Test b = new Test(1000);
a.equals(b) // return true.
}
}

II, Phương thức hashCode()

  • Phương thức hashCode() trả về 1 giá trị int. Gía trị hashCode được sử dụng phần lớn trong Collection sử dụng cơ chế hashing như HashMap, HashSet, HashTable
  • Một class override equals() thì class cũng nên override hashCode().
  • Một số lưu ý khi override hashCode():
    • Nếu x và y có equals() return true, hashCode() cũng phải trả về cùng 1 int trên cả x và y.
    • Nếu x và y có equals() return false, hashCode() không nhất thiết phải trả về 2 int khác nhau. Chúng có thể giống nhau nhưng trả về 2 int khác nhau sẽ giúp tăng performance cho các collection sử dụng cơ chế hashing.