Je veux savoir pourquoi .compareTo()
est dans l' Comparable
interface alors qu'une méthode comme .equals
est dans la Object
classe. Pour moi, il semble arbitraire pourquoi une méthode comme .compareTo()
n'est pas Object
déjà dans la classe.
Pour l'utiliser .compareTo()
, vous implémentez l' Comparable
interface et implémentez la .compareTo()
méthode à vos fins. Pour la .equals()
méthode, vous remplacez simplement la méthode dans votre classe, car toutes les classes héritent de la Object
classe.
Ma question est pourquoi une méthode est-elle comme .compareTo()
dans une interface que vous implémentez plutôt que dans une classe comme Object
? De même, pourquoi la .equals()
méthode dans la classe Object
et non dans une interface doit-elle être implémentée?
java
language-design
interfaces
Wesley
la source
la source
Eq
classe de types).Réponses:
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()
deuxThread
objets? Comment un fil est-il «supérieur à» un autre? Comment comparez-vous deuxArrayList<T>
s?Le
Object
contrat s'applique à toutes les classes Java. Si même une classe ne peut pas être comparée à d'autres instances de sa propre classe, elleObject
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 doiventComparable
pas implémenter niObject
avoir lacompareTo
méthode.Java efficace, 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 ne voulez imposer un ordre sur une non
Comparable
classe qui ne dispose pas d' un ordre naturel, vous pouvez toujours fournir unComparator
exemple pour aider les trier.la source
==
pour ce dernier, cela a un anneau creux. Sans tenir compte de la valeur par défaut redondante, on peut trouver des raisons valables de ne pas supposerequals
sur toutes les classes, car tous les types ne peuvent pas prendre en charge une relation d'équivalence.==
" parce que la façon dont ces classes sont instanciées est un détail d'implémentation mais le langage le rend impossible à masquer. On pourrait dire que quiconque compare deuxInteger
s par référence est un idiot, mais permettre à la comparaison de commencer est encore plus stupide.Le JLS §4.3.2 définit l'
class
objet de la manière suivante:C'est pourquoi
equals
c'est dansObject
maiscompareTo
dans une interface séparée. Je suppose qu'ils voulaient garderObject
le minimum possible. Ils ont probablement pensé que presque tousObjects
auraient besoinequals
ethashCode
(ce qui n'est vraiment qu'une forme de test d'égalité), mais tous les objets n'auraient pas besoin d'avoir un concept de classement , ce quicompareTo
est utilisé.la source
Equitable<T>
mais siObject
elle était implémentée, alors chaque classe serait unEquitable<Object>
. À ce stade, y a-t-il une différence? En effet pas vraiment, en complexité oui.object
aEquals(object)
, tout comme en Java, mais il y a aussi l'IEquatable<T>
interface. Bien que la raison principale de son existence soit d'éviter la boxe lorsqu'ilT
s'agit d'un type de valeur, ce qui n'est pas possible en Java.equals
est déclaréObject
directement:The methods equals and hashCode are declared for the benefit of hashtables such as java.util.Hashtable (§21.7)
- en tant que conception Java est rétrocompatible, le choix de conception Java 1.0 est la véritable raison d'equals
être là où il est.En plus de l'excellente réponse de Snowman, rappelez-vous qu'il s'agit d'
Comparable
une interface générique depuis longtemps. Un type n'implémente pascompareTo(object)
, il implémentecompareTo(T)
oùT
est son propre type. Cela ne peut pas être implémentéobject
, carobject
ne connaît pas la classe qui en sera dérivée.object
aurait pu définir unecompareTo(object)
méthode, mais cela aurait permis non seulement ce que Snowman souligne, une comparaison entre deuxArrayList<T>
s ou entre deuxThread
s, mais même une comparaison entre unArrayList<T>
et unThread
. C'est encore plus absurde.la source
Supposons que j'ai deux références d'objet: X identifie une instance de
String
contenu "George"; Y identifie l'instance dePoint
maintien des 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
etPoint
n'ayant 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 les relations de commande entre leurs instances, et certaines relations de commande peuvent même étendre sur plusieurs types [par exemple , il serait possible
BigInteger
etBigDecimal
de définir des méthodes de comparaison qui permettraient des instances de chaque type à être classés par rapport aux instances de l'autre], mais il n'est généralement pas possible de prendre deux instances arbitraires et de demander "Doit X trier avant, après ou équivalent à Y" et dériver un classement total. Il serait possible de demander "Si X doit trier avant, après, équivalent ou non classé par rapport à Y" si les objets étaient tenus de signaler un ordre cohérent mais pas un totalun, mais la plupart des algorithmes de tri nécessitent des commandes totales. Ainsi, même si tous les objets pouvaient implémenter unecompareTo
méthode si "non classé" était un retour valide, une telle méthode ne serait pas suffisamment utile pour justifier son existence.la source