Ao criar seu próprio objeto de par de chaves, você deve enfrentar algumas coisas.
Primeiro, você deve estar ciente de como implementar hashCode()
e equals()
. Você precisará fazer isso.
Em segundo lugar, ao implementar hashCode()
, certifique-se de entender como funciona. O exemplo de usuário fornecido
public int hashCode() {
return this.x ^ this.y;
}
é na verdade uma das piores implementações que você pode fazer. A razão é simples: você tem muitos hashes iguais! E o hashCode()
deve retornar valores int que tendem a ser raros, únicos na melhor das hipóteses. Use algo assim:
public int hashCode() {
return (X << 16) + Y;
}
Isso é rápido e retorna hashes exclusivos para chaves entre -2 ^ 16 e 2 ^ 16-1 (-65536 a 65535). Isso se encaixa em quase todos os casos. Muito raramente você está fora desses limites.
Terceiro, ao implementar equals()
também saiba para que serve e esteja ciente de como você cria suas chaves, uma vez que são objetos. Freqüentemente, você faz coisas desnecessárias se as declarações causam, você sempre terá o mesmo resultado.
Se você criar chaves como esta: map.put(new Key(x,y),V);
você nunca comparará as referências de suas chaves. Porque toda vez que você quiser acessar o mapa, você fará algo parecido map.get(new Key(x,y));
. Portanto, você equals()
não precisa de uma declaração como if (this == obj)
. Isso nunca vai acontecer .
Em vez de if (getClass() != obj.getClass())
em seu equals()
melhor uso if (!(obj instanceof this))
. Será válido até mesmo para subclasses.
Então, a única coisa que você precisa comparar é realmente X e Y. Portanto, a melhor equals()
implementação neste caso seria:
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;
}
Então, no final, sua aula principal é assim:
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;
}
}
Você pode fornecer seus índices de dimensão X
e Y
um nível de acesso público, pois são finais e não contêm informações confidenciais. Não tenho 100% de certeza se o private
nível de acesso funciona corretamente em qualquer caso ao transmitir o Object
para umKey
.
Se você quer saber sobre as finais, eu declaro qualquer coisa como final cujo valor é definido na instanciação e nunca muda - e, portanto, é uma constante de objeto.