Lorsque vous créez votre propre objet de paire de clés, vous devez faire face à plusieurs choses.
Tout d'abord, vous devez être conscient de la mise en œuvre hashCode()
y equals()
. Vous devrez le faire.
Deuxièmement, lors de la mise en œuvre hashCode()
assurez-vous de bien comprendre son fonctionnement. L'exemple d'utilisateur donné
public int hashCode() {
return this.x ^ this.y;
}
est en fait l'une des pires implémentations que l'on puisse faire. La raison est simple : vous avez beaucoup de hachages égaux ! Et les hashCode()
devrait renvoyer des valeurs int qui tendent à être rares, uniques dans le meilleur des cas. Utilisez quelque chose comme ceci :
public int hashCode() {
return (X << 16) + Y;
}
Cette méthode est rapide et renvoie des hachages uniques pour les clés comprises entre -2^16 et 2^16-1 (-65536 à 65535). Cela convient dans presque tous les cas. Il est très rare que vous soyez en dehors de cette limite.
Troisièmement, lors de la mise en œuvre equals()
Sachez également à quoi il sert et faites attention à la façon dont vous créez vos clés, puisqu'il s'agit d'objets. Souvent vous faites des déclarations if inutiles car 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 que chaque fois que vous voulez accéder à la carte, vous ferez quelque chose comme map.get(new Key(x,y));
. Par conséquent, votre equals()
n'a pas besoin d'une déclaration comme if (this == obj)
. Il jamais occultation.
Au lieu de if (getClass() != obj.getClass())
dans votre equals()
meilleure utilisation if (!(obj instanceof this))
. Il sera valable même pour les sous-classes.
Donc la seule chose que vous avez besoin de comparer est en fait X et Y. Donc le meilleur equals()
dans ce cas, la mise en œuvre serait :
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
y Y
un niveau d'accès public, du fait qu'ils sont définitifs et ne contiennent pas d'informations sensibles. Je ne suis pas sûr à 100% si private
Le niveau d'accès fonctionne correctement dans tout lors de l'introduction de la Object
à un Key
.
Si vous vous interrogez sur les finales, je déclare comme finale tout ce qui a une valeur fixée lors de l'instanciation et qui ne change jamais - et qui est donc une constante d'objet.