Khi bạn tạo đối tượng cặp khóa của riêng mình, bạn phải đối mặt với một số điều.
Đầu tiên, bạn nên biết về việc thực hiện hashCode()
và equals()
. Bạn sẽ cần phải làm điều này.
Thứ hai, khi thực hiện hashCode()
, hãy chắc chắn rằng bạn hiểu nó hoạt động như thế nào. Ví dụ người dùng nhất định
public int hashCode() {
return this.x ^ this.y;
}
thực sự là một trong những cách triển khai tồi tệ nhất mà bạn có thể làm. Lý do rất đơn giản: bạn có rất nhiều băm bằng nhau! Và hashCode()
nên trả về các giá trị int có xu hướng hiếm, tốt nhất là duy nhất. Sử dụng một cái gì đó như thế này:
public int hashCode() {
return (X << 16) + Y;
}
Điều này nhanh chóng và trả về số băm duy nhất cho các khóa từ -2 ^ 16 đến 2 ^ 16-1 (-65536 đến 65535). Điều này phù hợp với hầu hết mọi trường hợp. Rất hiếm khi bạn nằm ngoài giới hạn này.
Thứ ba, khi triển khai equals()
cũng phải biết nó được sử dụng để làm gì và nhận thức được cách bạn tạo khóa của mình, vì chúng là các đối tượng. Thường thì bạn làm không cần thiết nếu các câu lệnh gây ra bạn sẽ luôn có cùng một kết quả.
Nếu bạn tạo các khóa như thế này: map.put(new Key(x,y),V);
bạn sẽ không bao giờ so sánh các tham chiếu của các khóa của mình. Bởi vì mỗi khi bạn muốn gia nhập bản đồ, bạn sẽ làm điều gì đó như thế nào map.get(new Key(x,y));
. Do đó của bạn equals()
không cần một tuyên bố như thế nào if (this == obj)
. Nó sẽ không bao giờ xảy ra .
Thay vì sử dụng tốt hơn if (getClass() != obj.getClass())
của bạn . Nó sẽ có giá trị ngay cả đối với các lớp con.equals()
if (!(obj instanceof this))
Vì vậy, điều duy nhất bạn cần so sánh thực sự là X và Y. Vì vậy, cách equals()
triển khai tốt nhất trong trường hợp này sẽ là:
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
Vì vậy, cuối cùng lớp khóa của bạn là như thế này:
public class Key {
public final int X;
public final int Y;
public Key(final int X, final int Y) {
this.X = X;
this.Y = Y;
}
public boolean equals (final Object O) {
if (!(O instanceof Key)) return false;
if (((Key) O).X != X) return false;
if (((Key) O).Y != Y) return false;
return true;
}
public int hashCode() {
return (X << 16) + Y;
}
}
Bạn có thể cung cấp các chỉ số thứ nguyên X
và Y
cấp độ truy cập công khai, do chúng là chỉ số cuối cùng và không chứa thông tin nhạy cảm. Tôi không chắc 100% liệu private
cấp truy cập có hoạt động chính xác trong mọi trường hợp khi truyền Object
tới a hay không Key
.
Nếu bạn thắc mắc về kết quả cuối cùng, tôi tuyên bố bất kỳ điều gì là giá trị cuối cùng được đặt trên cá nhân và không bao giờ thay đổi - và do đó là một hằng số đối tượng.