Saat Anda membuat objek pasangan kunci Anda sendiri, Anda harus menghadapi beberapa hal.
Pertama, Anda harus menyadari penerapan hashCode()
dan equals()
. Anda harus melakukan ini.
Kedua, saat menerapkan hashCode()
, pastikan Anda memahami cara kerjanya. Contoh pengguna yang diberikan
public int hashCode() {
return this.x ^ this.y;
}
sebenarnya adalah salah satu penerapan terburuk yang dapat Anda lakukan. Alasannya sederhana: Anda memiliki banyak hash yang sama! Dan hashCode()
harus mengembalikan nilai int yang cenderung langka, unik yang terbaik. Gunakan sesuatu seperti ini:
public int hashCode() {
return (X << 16) + Y;
}
Ini cepat dan mengembalikan hash unik untuk kunci antara -2 ^ 16 dan 2 ^ 16-1 (-65536 hingga 65535). Ini cocok di hampir semua kasus. Sangat jarang Anda berada di luar batasan ini.
Ketiga, ketika mengimplementasikan equals()
juga tahu untuk apa itu digunakan dan menyadari bagaimana Anda membuat kunci Anda, karena mereka adalah objek. Seringkali Anda melakukan yang tidak perlu jika pernyataan menyebabkan Anda akan selalu mendapatkan hasil yang sama.
Jika Anda membuat kunci seperti ini: map.put(new Key(x,y),V);
Anda tidak akan pernah membandingkan referensi kunci Anda. Sebab setiap kali Anda ingin mengakses peta, Anda akan melakukan sesuatu seperti map.get(new Key(x,y));
. Oleh karena itu Anda equals()
tidak membutuhkan pernyataan seperti if (this == obj)
. Itu tidak akan pernah terjadi.
Daripada if (getClass() != obj.getClass())
Anda equals()
gunakan dengan lebih baik if (!(obj instanceof this))
. Ini akan berlaku bahkan untuk subclass.
Jadi satu-satunya hal yang perlu Anda bandingkan sebenarnya adalah X dan Y. Jadi equals()
penerapan terbaik dalam hal ini adalah:
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;
}
Jadi pada akhirnya kelas kunci Anda adalah seperti ini:
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;
}
}
Anda dapat memberikan indeks dimensi X
dan Y
tingkat akses publik, karena faktanya indeks tersebut final dan tidak berisi informasi sensitif. Saya tidak 100% yakin apakah private
tingkat akses berfungsi dengan benar dalam hal apa pun saat mentransmisikan Object
ke Key
.
Jika Anda bertanya-tanya tentang final, saya menyatakan apa pun sebagai final yang nilainya ditetapkan pada instancing dan tidak pernah berubah - dan oleh karena itu merupakan objek konstan.