Vimos como a equivalência se relaciona com a igualdade na ausência de ordem. Vejamos agora como se relaciona se a ordem estiver presente.
Pensemos no caso mais simples de um objeto que implemente Comparable
temos agora duas formas de saber se dois objetos são iguais:
// podemos usar equals()
assertTrue ( a.equals(b)) ;
// ou usar compareTo()
assertTrue ( a.compareTo(b) == 0 ) ;
Acontece que estes métodos não significam o mesmo, porque os objetos podem ser equivalentes sem serem iguais. Imaginemos uma classe Rational
definida assim:
class Rational {
int numerator;
int denominator;
Rational(int numerator, int denominator){
this.numerator = numerator;
this.denominator = denominator;
...
}
...
}
Vamos assumir que esta classe têm outros métodos para realizar operações e que deteta erros e lança exceções adquadamente. Assim, podemos escrever
Rational a = Rational(2, 6); // dois sextos
Rational b = Rational(1, 3); // um terço
Se usamos a.equals(b)
vamos obter false
pois o numerador e denominador não são iguais. Já se usarmos a.compareTo(b)
vamos obter 0
significando que são equivalentes.
Quando acontece isto, dizemos que a classe não implementa compareTo()
de forma compatível com equals
.
Portanto, como todos os objetos implementam equals
mas apenas alguns implementam Comparable
ao implementar compareTo
é preciso especificar se ele é compatível, ou não, com equals
. O método compareTo
diz-se compatível com equals
se , e apenas se, for verdade que:
se x.equals(y)
então x.compareTo(y) == 0
e x.compareTo(y) == 0
então x.equals(y)
Em cada SDK de cada linguagem é necessário conhecer quais objetos têm implementações incompatíveis. Em Java, por exemplo, BigDecimal
, Double
e Float
têm compareTo
não compatível com equals
.
Se queremos saber se um objeto é matematicamente igual a outro devemos sempre comparar usando compareTo
e nunca equals
.
Como boa prática tente sempre que as suas classes tenham a implementação de compareTo
compatível com equals
, isso remove confusões e bugs. Por exempplo, no caso do exemplo de Rational
se reduzimo sempre à fração mais baixa teremos ambas as propriedades consistentes entre si.