Je veux savoir pourquoi la .compareTo()
est dans l'interface Comparable
alors qu'une méthode comme .equals
Est dans Object
classe. Pour moi, il semble arbitraire pourquoi une méthode comme .compareTo()
n'est pas déjà dans la classe Object
.
Pour utiliser .compareTo()
, vous implémentez l'interface Comparable
et implémentez la méthode .compareTo()
selon vos besoins. Pour la méthode .equals()
, vous remplacez simplement la méthode dans votre classe, car toutes les classes héritent de la classe Object
.
Ma question est pourquoi une méthode comme .compareTo()
dans une interface que vous implémentez plutôt que dans une classe comme Object
? De même, pourquoi la méthode .equals()
dans la classe Object
et pas dans une interface doit-elle être implémentée?
Tous les objets ne peuvent pas être comparés, mais tous les objets peuvent être vérifiés pour leur égalité. Si rien d'autre, on peut voir si deux objets existent au même endroit en mémoire (égalité de référence).
Qu'est-ce que cela signifie pour compareTo()
sur deux Thread
objets? Comment un fil est-il "plus grand que" un autre? Comment comparez-vous deux ArrayList<T>
s?
Le contrat Object
s'applique à toutes Java classes. Si une seule classe ne peut pas être comparée à d'autres instances de sa propre classe, alors Object
ne peut pas exiger qu'elle fasse partie de l'interface.
Joshua Bloch utilise les mots clés "ordre naturel" pour expliquer pourquoi une classe pourrait vouloir implémenter Comparable
. Toutes les classes n'ont pas un ordre naturel comme je l'ai mentionné dans mes exemples ci-dessus, donc toutes les classes ne doivent pas implémenter Comparable
ni Object
avoir la méthode compareTo
.
... la méthode
compareTo
n'est pas déclarée dansObject
. ... Elle a un caractère similaire à la méthodeObject
deequals
, sauf qu'elle permet des comparaisons d'ordre en plus des comparaisons d'égalité simples, et elle est générique. En implémentantComparable
, une classe indique que ses instances ont un ordre naturel .
Efficace Java, deuxième édition : Joshua Bloch. Point 12, page 62. Les points de suspension suppriment les références à d'autres chapitres et exemples de code.
Pour les cas où vous voulez imposer un ordre à une classe non -Comparable
qui n'a pas d'ordre naturel, vous pouvez toujours fournissez une instance Comparator
pour faciliter le tri.
JLS §4.3.2 définit l'objet class
de la manière suivante:
4.3.2. L'objet de classe
La classe
Object
est une superclasse (§8.1.4) de toutes les autres classes.Tous les types de classe et de tableau héritent (§8.4.8) des méthodes de classe
Object
, qui se résument comme suit:
La méthode
clone
est utilisée pour créer un doublon d'un objet.La méthode
equals
définit une notion d'égalité d'objet, qui est basée sur une comparaison de valeur et non de référence.La méthode
finalize
est exécutée juste avant la destruction d'un objet (§12.6).La méthode
getClass
renvoie l'objet Class qui représente la classe de l'objet.Un objet
Class
existe pour chaque type de référence. Il peut être utilisé, par exemple, pour découvrir le nom complet d'une classe, ses membres, sa superclasse immédiate et toutes les interfaces qu'elle implémente.Le type d'une expression d'appel de méthode de
getClass
estClass<? extends |T|>
oùT
est la classe ou l'interface recherchée (§15.12.1) pourgetClass
.Une méthode de classe déclarée
synchronized
(§8.4.3.6) se synchronise sur le moniteur associé à l'objet Class de la classe.La méthode
hashCode
est très utile, avec la méthode equals, dans des tables de hachage telles queJava.util.Hashmap
.Les méthodes
wait
,notify
etnotifyAll
sont utilisées dans la programmation simultanée à l'aide de threads (§17.2).La méthode
toString
renvoie une représentation String de l'objet.
C'est pourquoi equals
est dans Object
mais compareTo
est dans une interface distincte. Je suppose qu'ils voulaient garder Object
aussi minimal que possible. Ils ont probablement pensé que presque tout Objects
aurait besoin de equals
et hashCode
(ce qui est vraiment juste une forme de test d'égalité) mais tous les objets n'auraient pas besoin d'avoir un concept d'ordre , qui est utilisé pour compareTo
.
En plus de l'excellente réponse de Snowman, rappelez-vous que Comparable
est depuis longtemps une interface générique. Un type n'implémente pas compareTo(object)
, il implémente compareTo(T)
où T
est son propre type. Cela ne peut pas être implémenté sur object
, car object
ne connaît pas la classe qui en sera dérivée.
object
aurait pu définir une méthode compareTo(object)
, mais cela aurait permis non seulement ce que Snowman souligne, une comparaison entre deux ArrayList<T>
s ou entre deux Thread
s, mais même une comparaison entre un ArrayList<T>
et un Thread
. C'est encore plus absurde.
Supposons que j'ai deux références d'objet: X identifie une instance de String
contenant le contenu "George"; Y identifie l'instance de Point
contenant les coordonnées [12,34]. Considérez les deux questions suivantes:
X et Y identifient-ils des objets équivalents?
Est-ce que X doit trier avant, après ou équivalent à Y?
Le fait que X et Y identifient des instances de types non liés ne pose aucun problème lors de l'examen de la première question. Les objets ne peuvent être considérés comme équivalents que si leurs types partagent une base commune qui les définit comme équivalents; puisque String
et Point
n'ont pas une telle base (leur seul type de base commun considère tous les objets distincts comme non équivalents) la réponse est simplement "non".
Le fait que les types ne soient pas liés, cependant, pose un énorme problème en ce qui concerne la deuxième question. Certains types définissent des relations de classement entre leurs instances, et certaines relations de classement peuvent même s'étendre sur plusieurs types [par exemple il serait possible pour BigInteger
et BigDecimal
de définir des méthodes de comparaison qui permettraient de classer les instances de chaque type par rapport aux instances de l'autre], mais il n'est généralement pas possible d'en prendre deux des instances arbitraires et demandez "Doit X trier avant, après ou équivalent à Y" et dériver un ordre total. Il serait possible de demander "Doit X trier avant, après, équivalent ou non classé par rapport à Y" si les objets devaient déclarer un ordre cohérent mais pas total un, mais la plupart des algorithmes de tri nécessitent des commandes totales. Ainsi, même si tous les objets pouvaient implémenter une méthode compareTo
si "non classé" était un retour valide, une telle méthode ne serait pas suffisamment utile pour justifier son existence.