Quiero saber por qué .compareTo()
está en la Comparable
interfaz mientras que un método como .equals
está en la Object
clase. Para mí, parece arbitrario por qué un método como .compareTo()
este no está en la Object
clase ya.
Para usar .compareTo()
, implementa la Comparable
interfaz e implementa el .compareTo()
método para sus propósitos. Para el .equals()
método, simplemente anule el método en su clase, ya que todas las clases heredan de la Object
clase.
Mi pregunta es ¿por qué es un método como .compareTo()
en una interfaz que implementa en lugar de en una clase como Object
? Del mismo modo, ¿por qué es el .equals()
método en la clase Object
y no en alguna de las interfaces a implementar?
java
language-design
interfaces
Wesley
fuente
fuente
Eq
clase de tipos).Respuestas:
No se pueden comparar todos los objetos, pero se puede verificar la igualdad de todos los objetos. Por lo menos, uno puede ver si existen dos objetos en la misma ubicación en la memoria (igualdad de referencia).
¿Qué significa para
compareTo()
dosThread
objetos? ¿Cómo es un hilo "mayor que" otro? ¿Cómo se comparan dosArrayList<T>
s?El
Object
contrato se aplica a todas las clases de Java. Si incluso una clase no puede compararse con otras instancias de su propia clase, entoncesObject
no puede requerir que sea parte de la interfaz.Joshua Bloch usa las palabras clave "ordenamiento natural" cuando explica por qué una clase podría querer implementar
Comparable
. No todas las clases tienen un orden natural como mencioné en mis ejemplos anteriores, por lo que no todas las clases deberían implementarComparable
ni deberíanObject
tener elcompareTo
método.Efectivo Java, segunda edición : Joshua Bloch. Elemento 12, página 62. Las elipses eliminan referencias a otros capítulos y ejemplos de código.
Para los casos en que no desea imponer un orden en un no-
Comparable
clase que no tiene un orden natural, siempre se puede suministrar unaComparator
instancia para ayudar a resolver la misma.fuente
==
para este último, tiene un anillo hueco. Sin tener en cuenta el valor predeterminado redundante, se pueden encontrar razones válidas para no asumirequals
en todas las clases, ya que no todos los tipos pueden admitir una relación de equivalencia.==
" porque la forma en que se instancian esas clases es un detalle de implementación, pero el lenguaje hace que sea imposible ocultarlo. Se podría decir que cualquiera que compare dosInteger
s por referencia es un idiota, pero permitir que la comparación comience es aún más tonta.El JLS §4.3.2 define el
class
objeto de la siguiente manera:Entonces, por eso
equals
está dentroObject
perocompareTo
está en una interfaz separada. Supondría que querían mantener loObject
más mínimo posible. Probablemente pensaron que casi todosObjects
necesitaríanequals
yhashCode
(que en realidad es solo una forma de prueba de igualdad), pero no todos los objetos necesitarían tener un concepto de ordenamiento , que es para lo quecompareTo
se utiliza.fuente
Equitable<T>
pero si seObject
implementa, entonces cada clase sería unEquitable<Object>
. En ese punto, ¿hay alguna diferencia? En efecto, no realmente, en complejidad sí.object
tieneEquals(object)
, al igual que en Java, pero también está laIEquatable<T>
interfaz. Aunque la razón principal para que exista es evitar el boxeo cuandoT
es un tipo de valor, lo cual no es posible en Java.equals
se declaraObject
directamente:The methods equals and hashCode are declared for the benefit of hashtables such as java.util.Hashtable (§21.7)
- como diseño de Java es compatible con versiones anteriores, la elección del diseño de Java 1.0 es la razón real deequals
estar donde está.Además de la excelente respuesta de Snowman, recuerde que
Comparable
ha sido una interfaz genérica durante mucho tiempo. Un tipo no se implementacompareTo(object)
, implementacompareTo(T)
dondeT
es su propio tipo. Esto no se puede implementarobject
, yaobject
que no conoce la clase que se derivará de él.object
podría haber definido uncompareTo(object)
método, pero esto habría permitido no solo lo que señala Snowman, una comparación entre dosArrayList<T>
so dosThread
s, sino incluso una comparación entre anArrayList<T>
y aThread
. Eso es aún más absurdo.fuente
Supongamos que tengo dos referencias de objeto: X identifica una instancia de
String
contenido "George"; Y identifica la instancia dePoint
mantener las coordenadas [12,34]. Considere las siguientes dos preguntas:¿X e Y identifican objetos equivalentes?
¿Debería X ordenar antes, después o equivalente a Y?
El hecho de que X e Y identifiquen instancias de tipos no relacionados no plantea ningún problema al considerar la primera pregunta. Los objetos solo pueden considerarse equivalentes si sus tipos comparten una base común que los define como equivalentes; desde
String
yPoint
no tienen tales base (su único tipo de base común se refiere a todos los objetos distintos como no-equivalente) la respuesta es simplemente "no".Sin embargo, el hecho de que los tipos no estén relacionados plantea un gran problema con respecto a la segunda pregunta. Algunos tipos definen relaciones de orden entre sus instancias, y algunas relaciones de orden pueden incluso extenderse sobre múltiples tipos [por ejemplo, sería posible
BigInteger
yBigDecimal
definir métodos de comparación que permitirían clasificar las instancias de cualquier tipo en relación con las instancias del otro], pero En general, no es posible tomar dos instancias arbitrarias y preguntar "Debería X ordenar antes, después o equivalente a Y" y derivar un orden total. Sería posible preguntar "¿Debería X ordenar antes, después, equivalente o sin clasificar con respecto a Y" si los objetos tuvieran que informar un orden consistente aunque no un total?uno, pero la mayoría de los algoritmos de ordenación requieren pedidos totales. Por lo tanto, incluso si todos los objetos pudieran implementar uncompareTo
método si "sin clasificar" fuera un retorno válido, dicho método no sería lo suficientemente útil como para justificar su existencia.fuente