Java Ssortingngs: compareTo () et égal à ()

En testant l’égalité de Ssortingng dans Java, j’ai toujours utilisé equals() car pour moi, cela semble être la méthode la plus naturelle. Après tout, son nom indique déjà ce qu’il est censé faire. Cependant, un de mes collègues m’a récemment appris à utiliser compareTo() == 0 au lieu de equals() . Cela ne semble pas naturel (car compareTo() est censé fournir un ordre et non pas comparer pour l’égalité) et même quelque peu dangereux (parce que compareTo() == 0 n’implique pas nécessairement l’égalité dans tous les cas, même si je le sais pour Ssortingng ‘ s) à moi.

Il ne savait pas pourquoi on lui avait appris à utiliser compareTo() au lieu de equals() pour Ssortingng , et je ne pouvais pas non plus trouver de raison. Est-ce vraiment une question de goût personnel, ou existe-t-il une véritable raison pour l’une ou l’autre de ces méthodes?

Une différence est que "foo".equals((Ssortingng)null) renvoie false alors que "foo".compareTo((Ssortingng)null) == 0 renvoie une exception NullPointerException. Ils ne sont donc pas toujours interchangeables, même pour les cordes.

Lorsque vous comparez pour l’égalité, vous devez utiliser equals() , car il exprime clairement votre intention.

compareTo() présente l’inconvénient supplémentaire de ne fonctionner que sur les objects implémentant l’interface Comparable .

Cela s’applique en général, pas seulement pour les chaînes.

Les deux principales différences sont les suivantes:

  1. equals prendra n’importe quel object comme paramètre, mais compareTo ne prendra que des chaînes.
  2. equals indique uniquement si elles sont égales ou non, mais compareTo donne des informations sur la façon dont les chaînes se comparent lexicographiquement.

J’ai jeté un coup d’oeil au code de la classe Ssortingng , et l’algorithme dans compareTo et égal est fondamentalement le même. Je crois que son opinion était juste une question de goût, et je suis d’accord avec vous – si tout ce que vous devez savoir, c’est l’égalité des cordes et non celle qui vient d’abord lexicographiquement, alors j’utiliserais des equals .

compareTo a plus de travail si les chaînes ont des longueurs différentes. equals peut juste retourner false, tandis que compareTo doit toujours examiner suffisamment de caractères pour trouver l’ordre de sorting.

En contexte de chaîne:
compareTo: Compare deux cordes lexicographiquement.
equals: Compare cette chaîne à l’object spécifié.

compareTo compare deux chaînes par leurs caractères (au même index) et renvoie un nombre entier (positif ou négatif) en conséquence.

 Ssortingng s1 = "ab"; Ssortingng s2 = "ab"; Ssortingng s3 = "qb"; s1.compareTo(s2); // is 0 s1.compareTo(s3); // is -16 s3.compareTo(s1); // is 16 

compareTo() ne s’applique pas seulement aux chaînes mais aussi à tout autre object car compareTo prend un argument générique T Ssortingng est l’une des classes qui a implémenté la méthode compareTo() en implémentant l’interface Comparable . (compareTo () est une méthode pour l’interface comparable). Ainsi, toute classe est libre d’implémenter l’interface Comparable.

Mais compareTo() donne l’ordre des objects , généralement utilisés pour sortinger les objects dans l’ordre croissant ou décroissant, alors que les equals() ne parlent que de l’égalité et indiquent s’ils sont égaux ou non.

equals () peut être plus efficace que compareTo () .

Une différence très importante entre compareTo et égale:

 "mySsortingng".compareTo(null); //Throws java.lang.NullPointerException "mySsortingng".equals(null); //Returns false 

equals () vérifie si deux objects sont identiques ou non et renvoie un booléen.

compareTo () (de l’interface Comparable) renvoie un entier. Il vérifie lequel des deux objects est “inférieur à”, “égal à” ou “supérieur à” l’autre. Tous les objects ne peuvent pas être ordonnés de manière logique, donc une méthode compareTo () n’a pas toujours de sens.

Notez que equals () ne définit pas l’ordre entre les objects, contrairement à compareTo ().

Maintenant, je vous conseille de revoir le code source des deux méthodes pour conclure qu’il est préférable à compareTo qui implique des calculs mathématiques.

Il apparaît que les deux méthodes font à peu près la même chose, mais la méthode compareTo () prend en compte un Ssortingng, pas un Object, et ajoute des fonctionnalités supplémentaires à la méthode equals () normale. Si tout ce qui vous intéresse est l’égalité, alors la méthode equals () est le meilleur choix, simplement parce que cela a plus de sens pour le prochain programmeur qui examine votre code. La différence de temps entre les deux fonctions ne devrait pas avoir d’importance, à moins que vous ne vous arrêtiez sur d’énormes quantités d’articles. Le compareTo () est vraiment utile lorsque vous devez connaître l’ordre des chaînes dans une collection ou lorsque vous devez connaître la différence de longueur entre les chaînes qui commencent par la même séquence de caractères.

source: http://java.sun.com/javase/6/docs/api/java/lang/Ssortingng.html

equals() devrait être la méthode de choix dans le cas de l’OP.

En regardant l’implémentation de equals() et compareTo() dans java.lang.Ssortingng sur grepcode , nous pouvons facilement voir que égal est préférable si nous nous intéressons uniquement à l’égalité de deux chaînes:

equals() :

  1012 booléens publics sont égaux ( Object anObject) { 
1013 if ( this == anObject) {
1014 retourne vrai ;
1015 }
1016 if (anObject instanceof Ssortingng ) {
1017 Ssortingng anotherSsortingng = ( Ssortingng ) anObject;
1018 int n = compte;
1019 si (n == anotherSsortingng.count) {
1020 caractères v1 [] = valeur;
1021 char v2 [] = anotherSsortingng.value;
1022 int i = offset;
1023 int j = anotherSsortingng.offset;
1024 tandis que (n--! = 0) {
1025 si (v1 [i ++]! = V2 [j ++])
1026 retourne faux ;
1027 }
1028 retourne vrai ;
1029 }
1030 }
1031 retourne faux ;
1032 }

et compareTo() :

  1174 public int compareTo ( Ssortingng anotherSsortingng) { 
1175 int len1 = count;
1176 int len2 = anotherSsortingng.count;
1177 int n = Math. min (len1, len2);
1178 caractères v1 [] = valeur;
1179 char v2 [] = anotherSsortingng.value;
1180 int i = offset;
1181 int j = anotherSsortingng.offset;
1183 si (i == j) {
1184 int k = i;
1185 int lim = n + i;
1186 tandis que (k 1187 caractères c1 = v1 [k];
1188 caractères c2 = v2 [k];
1189 si (c1! = C2) {
1190 retour c1 - c2;
1191 }
1192 k ++;
1193 }
1194 } sinon {
1195 tandis que (n--! = 0) {
1196 caractères c1 = v1 [i ++];
1197 char c2 = v2 [j ++];
1198 si (c1! = C2) {
1199 retourne c1 - c2;
1200 }
1201 }
1202 }
1203 retour len1 - len2;
1204 }

Lorsque l’une des chaînes est un préfixe d’un autre, les performances de compareTo() sont pires car il doit encore déterminer l’ordre lexicographique, alors que equals() ne s’inquiète plus et renvoie false immédiatement.

À mon avis, nous devrions utiliser ces deux comme ils étaient destinés:

  • equals() pour vérifier l’égalité, et
  • compareTo() pour trouver l’ordre lexical.

Il y a certaines choses que vous devez garder à l’esprit lorsque vous remplacez compareTo en Java. Par exemple, Compareto doit être compatible avec les égaux et la soustraction ne doit pas être utilisée pour comparer les champs entiers car ils peuvent déborder. check Choses à retenir lors de la substitution de Comparator en Java pour plus de détails.

Equals peut être plus efficace que compareTo.

Si la longueur des séquences de caractères dans Ssortingng ne correspond pas, les chaînes ne sont pas égales, ce qui signifie que le rejet peut être beaucoup plus rapide.

De plus, si c’est le même object (égalité d’identité plutôt qu’égalité logique), il sera également plus efficace.

S’ils implémentaient également la mise en cache du hashCode, il pourrait être encore plus rapide de rejeter les non-égaux au cas où leur hashCode ne correspondrait pas.

  1. equals peut prendre n’importe quel object en paramètre, mais compareTo ne peut prendre que de la chaîne.

  2. quand cometo null, compareTo lancera une exception

  3. Lorsque vous voulez savoir où le diff se produit, vous pouvez utiliser compareTo .

Ceci est une expérience de nécromancie 🙂

La plupart des réponses comparent les différences de performances et d’API. Ils manquent le point fondamental selon lequel les deux opérations ont simplement une sémantique différente.

Votre intuition est correcte. x.equals (y) n’est pas interchangeable avec x.compareTo (y) == 0. La première compare l’identité, tandis que l’autre compare la notion de «taille». Il est vrai que dans de nombreux cas, en particulier avec les types primitifs, ces deux co-alignent.

Le cas général est le suivant:

Si x et y sont identiques, ils partagent la même taille: si x.equals (y) est vrai => x.compareTo (y) est 0.

Cependant, si x et y partagent la même taille, cela ne signifie pas qu’ils sont identiques.

si x.compareTo (y) vaut 0, cela ne signifie pas nécessairement que x.equals (y) est vrai.

Un exemple convaincant où l’identité diffère de la taille serait un nombre complexe. Supposons que la comparaison se fasse par leur valeur absolue. Donc, étant donné deux nombres complexes: Z1 = a1 + b1 * i et Z2 = a2 + b2 * i:

Z1.equals (z2) renvoie true si et seulement si a1 = a2 et b1 = b2.

Cependant, Z1.compareTo (Z2) renvoie 0 pour et nombre infini de paires (a1, b1) et (a2, b2) tant qu’elles satisfont la condition a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2.

  • equals : requirejs pour vérifier l’égalité et limiter les doublons. De nombreuses classes de Java Library l’utilisent au cas où elles souhaiteraient trouver des doublons. Par exemple, HashSet.add(ob1) appenda uniquement si cela n’existe pas. Donc, si vous prolongez certaines classes comme celle-ci, alors substituez equals() .

  • compareTo : requirejs pour la commande de l’élément. Encore une fois pour un sorting stable, vous avez besoin d’une égalité, donc il y a un retour 0.

Ssortingng.equals() nécessite l’invocation de l’opérateur instanceof , tandis que compareTo() ne l’exige pas. Mon collègue a noté une baisse importante des performances due au nombre excessif d’appels instanceof dans la méthode equals() , mais mon test s’est avéré que compareTo() n’était que légèrement plus rapide.

J’utilisais cependant Java 1.6. Sur d’autres versions (ou d’autres fournisseurs JDK), la différence pourrait être plus grande.

Le test a comparé chaque chaîne de 1000 tableaux d’éléments, répété 10 fois.

Équivaut à –

1- Remplacez la méthode GetHashCode pour permettre à un type de fonctionner correctement dans une table de hachage.

2- Ne lancez pas d’exception dans l’implémentation d’une méthode Equals. Au lieu de cela, retournez false pour un argument nul.

3-

  x.Equals(x) returns true. x.Equals(y) returns the same value as y.Equals(x). (x.Equals(y) && y.Equals(z)) returns true if and only if x.Equals(z) returns true. 

Les invocations successives de x.Equals (y) renvoient la même valeur tant que l’object référencé par x et y n’est pas modifié.

 x.Equals(null) returns false. 

4- Pour certains types d’objects, il est souhaitable que Test Equals teste l’égalité des valeurs au lieu de l’égalité référentielle. De telles implémentations de Equals renvoient true si les deux objects ont la même valeur, même s’ils ne sont pas identiques.

Par exemple –

  Object obj1 = new Object(); Object obj2 = new Object(); Console.WriteLine(obj1.Equals(obj2)); obj1 = obj2; Console.WriteLine(obj1.Equals(obj2)); 

Sortie: –

 False True 

tandis que compareTo –

Compare l’instance actuelle avec un autre object du même type et renvoie un entier indiquant si l’instance actuelle précède, suit ou se produit dans la même position dans l’ordre de sorting que l’autre object.

Il revient –

Inférieur à zéro – Cette instance précède obj dans l’ordre de sorting. Zero – Cette instance se produit dans la même position dans l’ordre de sorting que obj. Supérieur à zéro – Cette instance suit obj dans l’ordre de sorting.

Il peut lancer une exception ArgumentException si object n’est pas du même type que l’instance.

Par exemple, vous pouvez visiter ici.

Je suggère donc de mieux utiliser Equals à la place de compareTo.

“est égal” compare les objects et retourne true ou false et “compare à” renvoie 0 si est vrai ou un nombre [> 0] ou [<0] si est faux ici un exemple:

  //Objects Integer Integer num1 = 1; Integer num2 = 1; //equal System.out.println(num1.equals(num2)); System.out.println(num1.compareTo(num2)); //New Value num2 = 3;//set value //diferent System.out.println(num1.equals(num2)); System.out.println(num1.compareTo(num2)); 

Résultats:

 num1.equals(num2) =true num1.compareTo(num2) =0 num1.equals(num2) =false num1.compareTo(num2) =-1 

Documentation Comparer à: https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html

Documentation égale: https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)

equals () vérifie si deux chaînes sont égales ou non. Il donne une valeur booléenne. compareTo () vérifie si l’object ssortingng est égal, supérieur ou inférieur à l’autre object ssortingng.Il donne le résultat suivant: 1 si l’object ssortingng est supérieur à 0 si les deux sont égaux à -1 si ssortingng est plus petit que l’autre chaîne

eq:

 Ssortingng a = "Amit"; Ssortingng b = "Sumit"; Ssortingng c = new Ssortingng("Amit"); System.out.println(a.equals(c));//true System.out.println(a.compareTo(c)); //0 System.out.println(a.compareTo(b)); //1 

Ici, une chose est importante en utilisant compareTo() sur equals() que compareTo fonctionne pour les classes qui implémentent l’interface ‘Comparable’, sinon une exception NullPointerException sera lancée. Ssortingng classes de Ssortingng implémentent une interface comparable, alors que SsortingngBuffer ne permet pas d’utiliser "foo".compareTo("doo") dans un object Ssortingng mais pas dans SsortingngBuffer Object.