Cuando crea su propio objeto de par de claves, debe enfrentar algunas cosas.
Primero, debe tener en cuenta la implementación de hashCode()
y equals()
. Necesitará hacer esto.
En segundo lugar, al implementarlo hashCode()
, asegúrese de comprender cómo funciona. El ejemplo de usuario dado
public int hashCode() {
return this.x ^ this.y;
}
es en realidad una de las peores implementaciones que puede hacer. La razón es simple: ¡tienes muchos hashes iguales! Y hashCode()
debería devolver valores int que tienden a ser raros, únicos en el mejor de los casos. Usa algo como esto:
public int hashCode() {
return (X << 16) + Y;
}
Esto es rápido y devuelve hashes únicos para claves entre -2 ^ 16 y 2 ^ 16-1 (-65536 a 65535). Esto encaja en casi cualquier caso. Muy rara vez estás fuera de estos límites.
En tercer lugar, al implementar equals()
también debes saber para qué se usa y ser consciente de cómo creas tus claves, ya que son objetos. A menudo hace declaraciones innecesarias porque siempre tendrá el mismo resultado.
Si crea claves como esta: map.put(new Key(x,y),V);
nunca comparará las referencias de sus claves. Porque cada vez que quieras acceder al mapa, harás algo como map.get(new Key(x,y));
. Por lo tanto equals()
, no necesita una declaración como if (this == obj)
. Será no aparecer dentro.
En lugar de if (getClass() != obj.getClass())
en su equals()
mejor uso if (!(obj instanceof this))
. Será válido incluso para subclases.
Entonces, lo único que necesita comparar es en realidad X e Y. Entonces, la mejor equals()
implementación en este caso sería:
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;
}
Entonces, al final, su clase clave es así:
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;
}
}
Puede dar sus índices de dimensión X
y Y
un nivel de acceso público, ya que son definitivos y no contienen información sensible. No estoy 100% seguro de si el private
nivel de acceso funciona correctamente en cualquier caso cuando se envía Object
a unKey
.
Si se pregunta acerca de las finales, declaro cualquier cosa como final cuyo valor se establece en la instanciación y nunca cambia, y por lo tanto es una constante de objeto.