Lorsque vous créez votre propre objet de paire de clés, vous devez faire face à certaines choses.
Tout d'abord, vous devez être conscient de la mise en œuvre hashCode()
et equals()
. Vous devrez le faire.
Deuxièmement, lors de la mise en œuvre hashCode()
, assurez-vous de comprendre comment cela fonctionne. L'exemple d'utilisateur donné
public int hashCode() {
return this.x ^ this.y;
}
est en fait l'une des pires implémentations que vous puissiez faire. La raison est simple: vous avez beaucoup de hachages égaux! Et le hashCode()
devrait renvoyer des valeurs int qui ont tendance à être rares, uniques au mieux. Utilisez quelque chose comme ceci:
public int hashCode() {
return (X << 16) + Y;
}
Ceci est rapide et renvoie des hachages uniques pour les clés entre -2 ^ 16 et 2 ^ 16-1 (-65536 à 65535). Cela convient à presque tous les cas. Très rarement, vous êtes hors de ces limites.
Troisièmement, lors de la mise en œuvre, equals()
sachez également à quoi il sert et soyez conscient de la façon dont vous créez vos clés, car ce sont des objets. Souvent, vous ne faites pas inutile si les déclarations provoquent vous aurez toujours le même résultat.
Si vous créez des clés comme ceci: map.put(new Key(x,y),V);
vous ne comparerez jamais les références de vos clés. Parce qu'à chaque fois que vous voudrez accéder à la carte, vous ferez quelque chose comme map.get(new Key(x,y));
. Par conséquent, vous equals()
n'avez pas besoin d'une déclaration comme if (this == obj)
. Cela n'arrivera jamais .
Au lieu de if (getClass() != obj.getClass())
votre equals()
meilleure utilisation if (!(obj instanceof this))
. Il sera valable même pour les sous-classes.
Donc, la seule chose que vous devez comparer est en fait X et Y. La meilleure equals()
implémentation dans ce cas serait donc:
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;
}
Donc, à la fin, votre classe de clé est comme ceci:
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;
}
}
Vous pouvez donner vos indices de dimension X
et Y
un niveau d'accès public, car ils sont définitifs et ne contiennent pas d'informations sensibles. Je ne suis pas sûr à 100% si le private
niveau d'accès fonctionne correctement dans tous les cas lors de la conversion du fichier Object
en a Key
.
Si vous vous interrogez sur la finale, je déclare n'importe quoi comme final dont la valeur est fixée à l'instanciation et ne change jamais - et est donc une constante d'objet.