Quando crei il tuo oggetto coppia di chiavi, dovresti affrontare alcune cose.
Innanzitutto, dovresti essere consapevole dell'implementazione di hashCode()
eequals()
. Avrai bisogno di farlo.
Secondo, durante l'implementazione hashCode()
, assicurati di capire come funziona. L'esempio utente fornito
public int hashCode() {
return this.x ^ this.y;
}
è in realtà una delle peggiori implementazioni che puoi fare. Il motivo è semplice: hai molti hash uguali! E hashCode()
dovrebbero restituire valori int che tendono ad essere rari, unici al meglio. Usa qualcosa del genere:
public int hashCode() {
return (X << 16) + Y;
}
È veloce e restituisce hash univoci per chiavi comprese tra -2 ^ 16 e 2 ^ 16-1 (da -65536 a 65535). Questo si adatta a quasi tutti i casi. Molto raramente sei fuori da questo limite.
Terzo, durante l'implementazione equals()
sappi anche a cosa serve e sii consapevole di come crei le tue chiavi, dato che sono oggetti. Spesso non è necessario fare dichiarazioni if perché avrai sempre lo stesso risultato.
Se crei chiavi in questo modo: map.put(new Key(x,y),V);
non confronterai mai i riferimenti delle tue chiavi. Perché ogni volta che vuoi accedere alla mappa, farai qualcosa di simile map.get(new Key(x,y));
. Quindi il tuo equals()
non ha bisogno di una dichiarazione come if (this == obj)
. Non accadrà mai .
Invece che if (getClass() != obj.getClass())
in un tuo equals()
uso migliore if (!(obj instanceof this))
. Sarà valido anche per le sottoclassi.
Quindi l'unica cosa che devi confrontare è in realtà X e Y. Quindi la migliore equals()
implementazione in questo caso sarebbe:
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;
}
Quindi alla fine la tua classe chiave è così:
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;
}
}
Puoi fornire i tuoi indici di dimensione X
e Y
un livello di accesso pubblico, poiché sono definitivi e non contengono informazioni sensibili. Non sono sicuro al 100% se il private
livello di accesso funzioni correttamente in ogni caso quando si trasmette il file Object
a un fileKey
.
Se ti chiedi quali sono le finali, dichiaro qualsiasi cosa come finale il cui valore è impostato sull'istanza e non cambia mai - e quindi è una costante dell'oggetto.