Quero saber por que o .compareTo()
está na Comparable
interface enquanto um método como .equals
está na Object
classe. Para mim, parece arbitrário o motivo de um método como esse .compareTo()
ainda não estar na Object
classe.
Para usar .compareTo()
, você implementa a Comparable
interface e implementa o .compareTo()
método para seus propósitos. Para o .equals()
método, você simplesmente substitui o método em sua classe, pois todas as classes são herdadas da Object
classe.
Minha pergunta é por que um método é semelhante a .compareTo()
uma interface que você implementa, e não a uma classe Object
? Da mesma forma, por que o .equals()
método da classe Object
e não em alguma interface deve ser implementado?
java
language-design
interfaces
Wesley
fonte
fonte
Eq
classe).Respostas:
Nem todos os objetos podem ser comparados, mas todos os objetos podem ser verificados quanto à igualdade. Se nada mais, é possível ver se existem dois objetos no mesmo local na memória (igualdade de referência).
O que isso significa
compareTo()
em doisThread
objetos? Como um segmento é "maior que" outro? Como você compara doisArrayList<T>
s?O
Object
contrato se aplica a todas as classes Java. Se nem uma classe puder ser comparada a outras instâncias de sua própria classe,Object
não será possível exigir que ela faça parte da interface.Joshua Bloch usa as palavras-chave "ordenação natural" ao explicar por que uma classe pode querer implementar
Comparable
. Nem toda classe tem uma ordem natural, como mencionei nos meus exemplos acima, portanto nem toda classe deve implementarComparable
nem deveObject
ter ocompareTo
método.Java eficaz, segunda edição : Joshua Bloch. Item 12, Página 62. As elipses removem referências a outros capítulos e exemplos de código.
Para os casos onde não querem impor uma ordenação em um não-
Comparable
classe que não tem uma ordem natural, você sempre pode fornecer umaComparator
instância para ajudar a resolver isso.fonte
==
para o último, isso tem um anel oco. Desconsiderando o padrão redundante, pode-se encontrar razões válidas para não assumirequals
em todas as classes, pois nem todos os tipos podem suportar uma relação de equivalência.==
", porque o modo como essas classes são instanciadas é um detalhe da implementação, mas a linguagem torna impossível ocultar. Você poderia dizer que qualquer um que compare doisInteger
s por referência é um idiota, mas permitir que a comparação comece ainda é mais tedioso.O JLS §4.3.2 define o
class
objeto da seguinte maneira:Então, é por isso que
equals
está dentro,Object
mascompareTo
está em uma interface separada. Eu especularia que eles queriam manterObject
o mínimo possível. Eles provavelmente imaginaram que quase todosObjects
precisariamequals
ehashCode
(que é realmente apenas uma forma de teste de igualdade), mas nem todos os objetos precisariam ter um conceito de ordenação , para o quecompareTo
é usado.fonte
Equitable<T>
mas seObject
implementada, então toda classe seria umaEquitable<Object>
. Nesse ponto, há alguma diferença? Na verdade, na verdade não, em complexidade, sim.object
temEquals(object)
, assim como em Java, mas também há aIEquatable<T>
interface. Embora o principal motivo para sua existência seja evitar o boxe quandoT
for um tipo de valor, o que não é possível em Java.equals
é declaradoObject
diretamente:The methods equals and hashCode are declared for the benefit of hashtables such as java.util.Hashtable (§21.7)
- como projeto em Java é compatível com versões anteriores, a escolha do design do Java 1.0 é a verdadeira razão deequals
estar onde está.Além da excelente resposta do Snowman, lembre-se de que essa
Comparable
interface é genérica há muito tempo. Um tipo não implementacompareTo(object)
, implementacompareTo(T)
ondeT
é seu próprio tipo. Isso não pode ser implementadoobject
, poisobject
não conhece a classe que será derivada dela.object
poderia ter definido umcompareTo(object)
método, mas isso teria permitido não apenas o que Snowman aponta, uma comparação entre doisArrayList<T>
s ou entre doisThread
s, mas também uma comparação entre umArrayList<T>
e aThread
. Isso é ainda mais absurdo.fonte
Suponha que eu tenha duas referências a objetos: X identifica uma instância de
String
retenção do conteúdo "George"; Y identifica a instância dePoint
retenção das coordenadas [12,34]. Considere as duas perguntas a seguir:X e Y identificam objetos equivalentes?
X deve classificar antes, depois ou equivalente a Y?
O fato de X e Y identificarem instâncias de tipos não relacionados não apresenta nenhum problema ao considerar a primeira pergunta. Objetos só podem ser considerados equivalentes se seus tipos compartilharem uma base comum que os define como equivalentes; uma vez que
String
ePoint
não possui essa base (seu único tipo de base comum considera todos os objetos distintos como não equivalentes), a resposta é simplesmente "não".O fato de os tipos não serem relacionados, no entanto, coloca um enorme problema em relação à segunda questão. Alguns tipos de definir relações de ordenação entre os seus casos, e algumas relações de ordenação pode mesmo estender-se por vários tipos [por exemplo, seria possível para
BigInteger
eBigDecimal
definir métodos de comparação que permitiriam instâncias de qualquer tipo para ser classificado em relação a instâncias do outro], mas em geral, não é possível tomar duas instâncias arbitrárias e perguntar "Deveria X ordenar antes, depois ou equivalente a Y" e derivar uma ordem total. Seria possível perguntar "Deve X ordenar antes, depois, equivalente ou sem classificação em relação a Y" se os objetos precisarem relatar uma ordem consistente, mas não um totalum, mas a maioria dos algoritmos de classificação exige pedidos totais. Assim, mesmo que todos os objetos pudessem implementar umcompareTo
método se "sem classificação" fosse um retorno válido, esse método não seria útil o suficiente para justificar sua existência.fonte