web-dev-qa-db-fra.com

Java Strings: compareTo () vs. equals ()

Lors du test d'égalité de String en Java, j'ai toujours utilisé equals() car cela me semble être la méthode la plus naturelle. Après tout, son nom dit déjà ce qu'il est censé faire. Cependant, un de mes collègues m'a récemment appris qu'on avait appris à utiliser compareTo() == 0 au lieu de equals(). Cela ne semble pas naturel (car compareTo() est censé fournir un ordre et non une comparaison pour l’égalité) et même quelque peu dangereux (car compareTo() == 0 n’implique pas nécessairement l’égalité dans tous les cas, même si je le sais pour String).

Il ne savait pas pourquoi on lui avait appris à utiliser compareTo() au lieu de equals() pour String, et je ne pouvais pas non plus en trouver la raison. Est-ce vraiment une question de goût personnel, ou y a-t-il une vraie raison pour l'une ou l'autre méthode?

108
Thomas Lötzer

Une différence est que "foo".equals((String)null) renvoie false alors que "foo".compareTo((String)null) == 0 lève une exception NullPointerException. Ils ne sont donc pas toujours interchangeables, même pour les chaînes.

92
waxwing

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

compareTo() a l'inconvénient supplémentaire de ne fonctionner que sur les objets qui implémentent l'interface Comparable.

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

26
starblue

Les 2 différences principales sont les suivantes:

  1. equals prendra n'importe quel objet en tant que paramètre, mais compareTo ne prendra que des chaînes.
  2. equals vous indique seulement 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'œil à le code de la classe String , et l'algorithme compris dans compareTo et égal a la même apparence. Je pense que son opinion n’est qu’une question de goût et je suis d’accord avec vous. Si tout ce que vous avez besoin de savoir, c’est l’égalité des cordes et non laquelle est la première, lexicographiquement parlant, j’utiliserais equals.

25
Kaleb Brasee

compareTo doit faire plus de travail si les chaînes ont des longueurs différentes. equals peut simplement retourner false, alors que compareTo doit toujours examiner suffisamment de caractères pour trouver l'ordre de tri.

16
robinr

En contexte de chaîne:
compareTo: Compare deux chaînes lexicographiquement.
equals: Compare cette chaîne à l'objet spécifié.

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

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

compareTo() s'applique non seulement aux chaînes, mais également à tout autre objet, car compareTo<T> accepte un argument générique T. String est l'une des classes qui a implémenté la méthode compareTo() en implémentant l'interface Comparable.(compareTo () est une méthode d’interface comparable). Toute classe est donc libre d'implémenter l'interface Comparable. 

Mais compareTo() donne l'ordre des objets , utilisé généralement pour trier les objets par ordre croissant ou décroissant, tandis queequals() ne fera que parler de l'égalité et indiquera s'ils sont égaux ou non.

8
apurva jadhav

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

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

"myString".compareTo(null);  //Throws Java.lang.NullPointerException
"myString".equals(null);     //Returns false

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

compareTo () (à partir de l'interface Comparable) renvoie un entier. Il vérifie lequel des deux objets est "inférieur à", "égal à" ou "supérieur à" l'autre. Tous les objets ne peuvent pas être ordonnés logiquement, aussi une méthode compareTo () n'a pas toujours de sens. 

Notez que equals () ne définit pas l'ordre entre les objets, ce que compareTo (). 

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

6
Jaimin Patel

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.String sur grepcode , nous pouvons facilement voir que l'égalité est meilleure si nous nous préoccupons uniquement de l'égalité de deux chaînes:

equals():

compareTo():

compareTo() sont encore pires car il lui reste à 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 la commande lexicale.
5
prk

Il semble que les deux méthodes fassent pratiquement la même chose, mais la méthode compareTo () prend une chaîne, pas un objet, et ajoute des fonctionnalités supplémentaires par-dessus la méthode normale equals (). Si l'égalité ne tient qu'à vous, alors la méthode equals () est le meilleur choix, tout 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 lisiez une quantité énorme d’articles. 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/String.html

5
Scott M.

Il y a certaines choses que vous devez garder à l'esprit lors de la substitution de compareTo en Java, par exemple. Compareto doit être cohérent avec égal et la soustraction ne doit pas être utilisée pour comparer des champs entiers car ils peuvent déborder. check Ce qu'il faut retenir lors du remplacement de Comparator en Java pour plus de détails.

2
Seema Kiran

String.equals() nécessite l'invocation deinstanceofoperator, tandis que compareTo() nécessite pas. Mon collègue a noté une baisse importante des performances provoquée par un nombre excessif de méthodesinstanceofdans la méthode equals(). Toutefois, mon test s'est révélé être compareTo() 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 dans des tableaux de 1000 éléments, répétés 10 fois. 

2
Danubian Sailor

Equals peut être plus efficace que compareTo.

Si la longueur des séquences de caractères dans String ne correspond pas, il n'y a aucun moyen que les chaînes soient égales, ainsi le rejet peut être beaucoup plus rapide.

De plus, s'il s'agit du même objet (égalité d'identité plutôt que logique), il sera également plus efficace.

S'ils implémentaient également la mise en cache hashCode, le rejet des non-égaux pourrait être encore plus rapide au cas où leur hashCode ne correspond pas.

2
Gopal Rajpurohit
  • equals: nécessaires pour vérifier l’égalité et limiter les doublons. De nombreuses classes de Java Library l'utilisent au cas où elles souhaitaient trouver des doublons. par exemple. HashSet.add(ob1) n’ajoutera que s’il n’existe pas. Donc, si vous étendez certaines classes comme celle-ci, remplacez equals().

  • compareTo: nécessaire pour commander un élément. Encore une fois, pour un tri stable, vous avez besoin d’égalité, il ya donc un retour 0.

1
Dillip Rout
  1. equals peut prendre n'importe quel objet en tant que paramètre mais compareTo ne peut prendre que String.

  2. quand arrive à null, compareTo lève une exception

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

1
littletiger

C'est une expérience de nécromancie :-)

La plupart des réponses comparent les performances et les différences entre les API. Ils oublient 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 . Le premier 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 ont la même taille, cela ne signifie pas qu’elles sont identiques.

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

Un exemple probant où identité diffère de la taille serait constitué par des nombres complexes. 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 un nombre infini de paires (a1, b1) et (a2, b2) tant qu'elles satisfont à la condition a1 ^ 2 + b1 ^ 2 == a2 ^ 2 + b2 ^ 2.

1
Vitaliy

equals () vérifie si deux chaînes sont égales ou non.Il donne une valeur booléenne . compareTo () vérifie si l'objet chaîne est égal ou supérieur à l'autre objet chaîne.Il donne le résultat suivant: l'objet string est supérieur à 0 si les deux sont égaux - 1 si la chaîne est plus petite que les autres

eq:

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

"equals" compare les objets et renvoie true ou false et "compare à" renvoie 0 si true ou un nombre [> 0] ou [<0] si false voici un exemple:

<!-- language: lang-Java -->
//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 Comparez à: 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)

0
David Hackro

Je crois que égaux et equivalents les méthodes de String renvoient true et false, ce qui est utile si vous souhaitez comparer les valeurs de l'objet string, mais en cas de mise en œuvre compareTo et compareToIgnoreCase méthodes renvoie des valeurs positives, négatives et nulles qui seront utiles en cas de tri.

0
Prakhar Aditya

Ici, une chose est importante lorsqu’on utilise compareTo() sur equals() que compareTo fonctionne pour les classes qui implémentent l’interface 'Comparable', sinon une valeur NullPointerException sera lancée. Les classes String implémentent une interface comparable alors que StringBuffer ne permet pas d'utiliser "foo".compareTo("doo") dans un objet String mais pas dans un objet StringBuffer.

0
Pratik

Équivaut à -

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

2- Ne lancez pas une exception dans la mise en œuvre d'une méthode Equals Au lieu de cela, renvoyer false pour un argument null.

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'objet référencé par x et y n'est pas modifié.

x.Equals(null) returns false.

4- Pour certains types d'objets, il est souhaitable que le test Egals soit égal à l'égalité des valeurs et non à l'égalité référentielle. De telles implémentations de Equals retournent true si les deux objets ont la même valeur, même s'ils ne sont pas la même instance.

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 objet du même type et renvoie un entier indiquant si l'instance actuelle précède, suit ou se produit à la même position dans l'ordre de tri de l'autre objet.

Il retourne -

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

Il peut renvoyer une ArgumentException si l'objet n'est pas du même type que l'instance.

Par exemple, vous pouvez visiter ici.

Je suggère donc de mieux utiliser Equals au lieu de compareTo.

0
Prabhat Jain