Quiero saber por qué .compareTo()está en la Comparableinterfaz mientras que un método como .equalsestá en la Objectclase. Para mí, parece arbitrario por qué un método como .compareTo()este no está en la Objectclase ya.
Para usar .compareTo(), implementa la Comparableinterfaz 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 Objectclase.
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 Objecty no en alguna de las interfaces a implementar?
java
language-design
interfaces
Wesley
fuente
fuente

Eqclase 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()dosThreadobjetos? ¿Cómo es un hilo "mayor que" otro? ¿Cómo se comparan dosArrayList<T>s?El
Objectcontrato se aplica a todas las clases de Java. Si incluso una clase no puede compararse con otras instancias de su propia clase, entoncesObjectno 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 implementarComparableni deberíanObjecttener elcompareTomé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-
Comparableclase que no tiene un orden natural, siempre se puede suministrar unaComparatorinstancia 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 asumirequalsen 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 dosIntegers 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
classobjeto de la siguiente manera:Entonces, por eso
equalsestá dentroObjectperocompareToestá en una interfaz separada. Supondría que querían mantener loObjectmás mínimo posible. Probablemente pensaron que casi todosObjectsnecesitaríanequalsyhashCode(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 quecompareTose utiliza.fuente
Equitable<T>pero si seObjectimplementa, entonces cada clase sería unEquitable<Object>. En ese punto, ¿hay alguna diferencia? En efecto, no realmente, en complejidad sí.objecttieneEquals(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 cuandoTes un tipo de valor, lo cual no es posible en Java.equalsse declaraObjectdirectamente: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 deequalsestar donde está.Además de la excelente respuesta de Snowman, recuerde que
Comparableha sido una interfaz genérica durante mucho tiempo. Un tipo no se implementacompareTo(object), implementacompareTo(T)dondeTes su propio tipo. Esto no se puede implementarobject, yaobjectque no conoce la clase que se derivará de él.objectpodrí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 dosThreads, 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
Stringcontenido "George"; Y identifica la instancia dePointmantener 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
StringyPointno 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
BigIntegeryBigDecimaldefinir 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 uncompareTométodo si "sin clasificar" fuera un retorno válido, dicho método no sería lo suficientemente útil como para justificar su existencia.fuente