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 Xe Yum 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 privatenível de acesso funciona corretamente em qualquer caso ao transmitir o Objectpara 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.